要修改属性,应使用setAttributes()
与代码中其他地方的操作相同。此函数用于更新古腾堡数据存储中的值,从而触发任何组件的重新渲染,并在保存帖子时在数据库中分期更新更改。
const { width } = props.attributes;
const { color } = props.attributes;
const { highlight } = props.attributes;
const combo = width + \' \' + color + \' \' + highlight;
if ( combo ) {
props.attributes.className = `${ combo }`;
}
此外,在此代码中
if( combo )
条件将始终执行,因为
combo
赋值将始终计算为非空字符串,即;“真实的”;在JavaScript中。如果
width
,
color
, 和
highlight
未定义,
combo
成为字符串
"undefined undefined undefined"
, 对于HTML类名来说,这似乎是不可取的。
我认为在每个属性派生类名前面加上前缀是一个好主意,这样您就可以将它们彼此区分开来,例如。att-highlight-red
而不是red
. 将键/值对的对象转换为类名并忽略未定义值的函数对此非常有用:
function attsToClassNames( atts = {} ) {
const classes = [];
for( const [ key, value ] in Object.entries( atts ) ) {
if( ! value && value !== 0 ) // Ignore falsey values, except 0
continue;
classes.push( `att-${key}-${value}` );
}
return classes;
}
考虑到以上所有内容,我将用以下内容替换此答案开头引用的代码部分:
const {
attributes,
setAttributes,
} = props;
const {
width,
color,
highlight,
className,
} = attributes;
// Retrieve the current attribute classes.
const attClasses = attsToClassNames( { width, color, highlight } ).join( \' \' );
// If the `className` attribute does not reflect the current attribute classes,
// update it.
if( className !== attClasses )
setAttributes( { className: attClasses } );
现在
className
应始终反映从其他属性派生的最新类名列表,并将与post&;的其余部分一起保存在Gutenberg的数据存储中;块属性。
为了提高效率(非常轻微),我们可以利用ReactuseEffect()
挂钩(从导入@wordpress/element
) 并在;依赖关系数组-这将使重建属性类仅在第一次渲染时发生,然后仅当其中一个或多个属性在此之后发生更改时发生:
useEffect(
() => {
const attClasses = attsToClassNames( { width, color, highlight } ).join( \' \' );
if( className !== attClasses )
setAttributes( { className: attClasses } );
},
[ width, color, highlight ]
);
这可能仍然会带来一些其他潜在问题,具体取决于您的特定用例-即如果您希望合并任何其他外部
className
就像传来的一样
props
.