状态更改后,复选框未更改检查属性

时间:2017-03-23 14:30:09

标签: reactjs checkbox redux

以下是我正在使用的代码的一些部分:

class FileItem extends Component {

  constructor(props) {
    super(props);

    // Initial state
    this.state = {
      hover: false,
      checked: false
    };

    this.pickFile = this.pickFile.bind(this);  

  }

  pickFile(e){
   e.stopPropagation();
   this.state.checked ? this.props.removeSelectedPaths(this.props.path) : this.props.addSelectedPaths(this.props.path);
  }

  //set the checked status for the checkboxes if file\folder are picked
  componentWillReceiveProps(nextProps){

   this.setState({checked: nextProps.selectedPaths.indexOf(this.props.path) != -1 });

 } 

 render(){

  return(          
      <div className='select-mode'><input id='files-select' type='checkbox'  checked={this.state.checked} onClick={this.pickFile}/></div>
  )

 }

这应该如何运作:

选择文件时,应设置其复选框的选中状态。当你使用slect all files复选框时(它不在这里的代码中)它将所有路径推送到selectedPAths数组中的redux状态,并且所有文件都应该选中复选框。

组件结构:

  1. 文件 - 连接到redux状态的容器。发送道具到FileList
  2. FileList - 每个FileItem的哑组件包装器。将道具发送到FileItem。
  3. FileItem - 为特定文件呈现行的组件
  4. 问题:

    问题是,当我使用“选择所有文件”功能时,单个文件的复选框不会更新UI以显示复选框上的复选标记。虽然按文件选择文件工作正常,但复选框更改为已选中(但使用相同的逻辑来查看是否应该检查)。

    奇怪的事实:

    1. 当我这样做的时候 渲染中的 console.log(this.state.checked)它向我显示状态为 的即可。所以它应该更改复选框以检查但不是。
    2. 我对Select All files复选框有一个类似的逻辑(它使用componentWillReceiveProps方法检查是否所有文件都被选中并更改了检查状态)并且它工作正常。
    3. 您可以在选择刚悬停的所有文件后显示复选框已选中(这会触发鼠标输入事件并更改导致重新渲染的状态)。我感觉状态改变之后渲染就会丢失,但是奇怪的事实1告诉了相反的事情,因为我们在状态中有 true 但在UI中没有选中复选框。

1 个答案:

答案 0 :(得分:0)

有时组件需要密钥,通常在使用列表时。这对于检测更改很有用。试试这个:

<FileItem key={file.index.toString() + file.isChecked} path={filepath} checked={file.isChecked} />

我们说要做出改变的反应。重新渲染。

<强>推荐: 如果要处理所有项目的状态,则必须从父项传递已检查的参数

files.map (file => 
     <fileItem key={file.key} path={filepath} checked={AllChecked} />

并在FileItem:

class FileItem extends Component {

  constructor(props) {
    super(props);

    // Initial state
    this.state = {
      hover: false,
      checked: props.checked// <= here
    };

    this.pickFile = this.pickFile.bind(this);  

  }