我也有一个React组件,我也试图设置一个“活动”类。这是我用来测试是否应该设置活动类的代码。
{sku.colors &&
(<div className="swatches" styleName="swatches">
<span className="color" styleName="color" data-name="color">
{sku.colors.map((option, index) => {
return(
<span className={this.state.selectedColor === option.name ? 'active': ''} styleName="swatch" onClick={this.onColorChange.bind(this, option.name)} style={{backgroundImage: 'url(' + swatchImg + ')' }} key={index}>{option.name}</span>
)
})}
</span>
</div>)
}
我将state.selectedColor定义为道具
constructor(props) {
super(props);
this.state = { selectedColor: 'Black' };
}
这是我的onClick函数:
onColorChange(currentColor){
//add sizes for this color
this.state.selectedColor = currentColor;
}
问题是仅在首次加载组件时才检查是否是否selectedColor = option.name。在onClick函数触发后不会再次进行检查,因此活动类永远不会更新。
我想我可能需要在onClick事件之后重新渲染该部分。有没有人对解决此问题有任何意见/建议?
编辑:我可以看到state.selectedColor在click事件上被正确更新,但是活动类检查不起作用。
我添加了:
console.log(this.state.selectedColor);
,点击后确实可以正确更新。
答案 0 :(得分:2)
您应该使用this.setState({ selectedColor: currentColor })
而不是this.state.selectedColor = currentColor
。您永远不要尝试通过直接为它们分配值来更新状态属性。这可能就是为什么还没有触发重新提交的原因。
这在React Docs中也有说明:state
答案 1 :(得分:2)
您的直觉是正确的,在修改-XX:+UseG1GC
之后,您确实需要重新渲染。
使用state.selectedColor
函数将更新您的状态,然后立即启动重新渲染。这是React提供的工具,因为这是一种常见的操作(即更改状态然后重新渲染)。
要记住的一件事是,在this.setState({selectedColor: currentColor})
函数内部使用setState
可能会导致无限循环。
答案 2 :(得分:1)
尝试:
onColorChange(currentColor){
//add sizes for this color
this.setState({selectedColor: currentColor});
}
答案 3 :(得分:1)
您确定自己所做的一切正确吗?它在这里工作:
const sku = {
colors: [
{ id: 1, name: "Black" },
{ id: 2, name: "Red" },
{ id: 3, name: "White" },
],
};
class App extends React.Component {
state = {
selectedColor: "Red"
};
onColorChange ( currentColor ) {
this.setState( { selectedColor: currentColor } );
}
render() {
return (
<div>
{sku.colors && (
<div className="swatches" styleName="swatches">
<span className="color" styleName="color" data-name="color">
{sku.colors.map((option, index) => (
<span
className={
this.state.selectedColor === option.name ? "active" : ""
}
styleName="swatch"
onClick={this.onColorChange.bind(this, option.name)}
key={index}
>
{option.name}
</span>
))}
</span>
</div>
)}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
.active {
font-size: 20px;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
此外,如果将每个option
提取到其组件中,则无需直接在JXS中绑定函数。因此,不会在每个渲染中都创建它。如果像这样使用它或使用箭头功能,它将在每个渲染中创建。另外,如果您查看控制台,React会警告您将styleName
属性用作stylename
。
const sku = {
colors: [
{ id: 1, name: "Black" },
{ id: 2, name: "Red" },
{ id: 3, name: "White" },
],
};
class App extends React.Component {
state = {
selectedColor: "Red",
};
onColorChange = currentColor =>
this.setState( { selectedColor: currentColor } );
render() {
return (
<div>
{sku.colors && (
<div className="swatches" styleName="swatches">
<span className="color" styleName="color" data-name="color">
{sku.colors.map( option => (
<Option
key={option.id}
option={option}
selectedColor={this.state.selectedColor}
onColorChange={this.onColorChange}
/>
) )}
</span>
</div>
)}
</div>
);
}
}
const Option = ( props ) => {
const { option, selectedColor, onColorChange } = props;
const handleChange = () => onColorChange( option.name );
return (
<span
className={
selectedColor === option.name ? "active" : ""
}
styleName="swatch"
onClick={handleChange}
>
{option.name}
</span>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
.active {
font-size: 20px;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>