有条件地应用在点击次数上发生变化的类

时间:2018-09-12 20:13:20

标签: javascript jquery reactjs reactive-programming

我也有一个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);

,点击后确实可以正确更新。

4 个答案:

答案 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>