无状态组件中的React复选框不会立即更新

时间:2017-04-12 03:03:28

标签: reactjs checkbox

我使用复选框创建了一个基本界面,该复选框使用了反应设计模式,该模式以前很好用,并且我思想运行良好 - 即提升状态并将道具传递给UI组件。我的复选框组件传递一个值(一个度量),一个状态更改方法和一个用于checked的布尔值。问题是复选框不会立即更新,即使您可以在React开发工具中看到它们更新。它们仅在下次单击时更新,如同选中另一个复选框时一样。这是代码:

class App extends React.Component {
 constructor(props) {
  super(props);
  this.state = {
   metricsSelected: []
  }
  this.selectMetric = this.selectMetric.bind(this)
 }

selectMetric(metric) {
 const metricsSelected = this.state.metricsSelected
 const index = metricsSelected.indexOf(metric)
 if (index !== -1){
  metricsSelected.splice(index, 1)
 }
 else {
  metricsSelected.push(metric)
 }
 this.setState({
  metricsSelected,
 });
}

render() {
 return (
  <div>
    <Sidebar
      metricsSelected={this.state.metricsSelected}
      selectMetric={this.selectMetric}/>
    <SomethingElse/>
   </div>
  )
 }
}

const SomethingElse = () => (<div><h2>Something Else </h2></div>)

const Sidebar = ({ metricsSelected, selectMetric }) => {
 const metrics = ['first thing', 'second thing', 'third thing']
 return (
  <div>
   <h3>Select Metrics</h3>
   { metrics.map( (metric, i) =>
    <Checkbox
      key={i}
      metric={metric}
      selectMetric={selectMetric}
      checked={metricsSelected.includes(metric)}/>
    )}
   </div>
  )
 }

const Checkbox = ({ metric, selectMetric, checked }) => {

const onChange = e => {
 e.preventDefault()
 selectMetric(e.target.value)
}
return (
  <ul>
   <li>{metric}</li>
   <li><input
   type='checkbox'
   value={metric}
   checked={checked}
   onChange={onChange} /></li>
  </ul>
 )
}

我已经阅读了几乎所有关于复选框复选框的内容,而复选框的大多数应用程序都在做与我想做的事情不同的事情。我已经尝试将状态添加到Checkbox组件,但这似乎没有帮助,因为检查的值仍然需要从其他地方进来。当道具改变时,我认为反应组件会被重新渲染。是什么赋予了?

这是一个codepen:https://codepen.io/matsad/pen/QpexdM

1 个答案:

答案 0 :(得分:0)

以下是工作版本:http://codepen.io/TLadd/pen/oWvOad?editors=1111

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      metricsSelected: {}
    }
    this.selectMetric = this.selectMetric.bind(this)
  }

  selectMetric(metric) {
    this.setState(({ metricsSelected }) => ({
      metricsSelected: {
        ...metricsSelected,
        [metric]: !metricsSelected[metric]
      }
    }))
  }

  render() {
    return (
      <div>
        <Sidebar
          metricsSelected={this.state.metricsSelected}
          selectMetric={this.selectMetric}/>
        <SomethingElse/>
      </div>
    )
  }
}

const SomethingElse = () => (<div><h2>Something Else </h2></div>)

const Sidebar = ({ metricsSelected, selectMetric }) => {
  const metrics = ['first thing', 'second thing', 'third thing']
  return (
    <div>
      <h3>Select Metrics</h3>
      { metrics.map( (metric, i) =>
        <Checkbox
          key={i}
          metric={metric}
          selectMetric={selectMetric}
          checked={Boolean(metricsSelected[metric])}/>
        )}
    </div>
  )
}

const Checkbox = ({ metric, selectMetric, checked }) => {
  return (
  <ul>
    <li>{metric}</li>
    <li>
      <input
        type='checkbox'
        name={metric}
        checked={checked}
        onChange={() => selectMetric(metric)} 
       />
     </li>
   </ul>
  )
}


ReactDOM.render(
  <App />,
  document.getElementById('root')
);

引起问题的几件事情是你在selectMetric中改变状态,而你的复选框输入的onChange函数使用e.target.value而不是e.target.checked。

我将metricsSelected状态更改为对象,因为我认为它使管理更加容易。