1

我使用 React 检索带有复选框的数组数据。但是,如果我选中一个复选框,它会选中所有复选框。如果我选中一个复选框,我想显示一个文本框。我该如何解决?

class ColumnName extends Component {
  constructor(props) {
    super(props);
    this.state = { checked: false };
  }
  render() {
    if (!this.props.posts) {
      return <div />;
    }
    const content = this.state.checked ? <div> Content </div> : null;
    return (
      <ul>
        {this.props.posts.map(post => (
          <div>
            <Checkbox
              checked={this.state.checked}
              onChange={() => {
                this.setState({
                  checked: !this.state.checked
                });
              }}
            >
              {post.title}
            </Checkbox>
            {content}
          </div>
        ))}
      </ul>
    );
  }
}

export default Search;
4

5 回答 5

2

我解决了那个问题。这是我的代码,我将尝试解释它。首先,我创建了一个对象数组。

const dogsData = [
{
    name: 'Jackey',
    src: require('./Images/dog-1.jpg'),
    id: 1,
    completed: false
}, {
    name: 'Molly',
    src: require('./Images/dog-2.jpg'),
    id: 2
    completed: false
}, {
    name: 'Spyke',
    src: require('./Images/dog-3.jpg'),
    id: 3,
    completed: false
},


]
export default dogsData;'

然后我将该数组添加到我的状态中,并为其中的每个对象创建了一个组件this.state.dogs并将其添加到道具----

import dogsData from './components/dogsData'

constructor() {
super();
this.state = {
  dogs: dogsData,  //dogsData in state
}

const dogs = this.state.dogs.map(dog => {
  return (
    <Dogs dog={dog} key={dog.id} handleChange={this.handleChange} />
  )'

handleChange方法,将其添加到复选框onChange事件

handleChange(id) {
this.setState(prevState => {
  const updatedDogs = prevState.dogs.map(dog => {
    if (dog.id === id) {                
      dog.completed = !dog.completed    
    }
    else {                                      
      dog.completed = false
    }
    return dog
  })
  return {
    dogs: updatedDogs,
  }

})'
于 2019-06-15T14:36:17.743 回答
1

您有一组帖子,并且您想为每个帖子(出现)呈现一个复选框。您对所有复选框的选中值都有一个状态值,在更改时您会为每个复选框更新此选中值。

所以这是你的问题。为每个复选框使用不同的选中状态,但另一个选项可能类似于:

class ColumnName extends Component {
  constructor(props) {
    super(props);
    this.state = { selected: null };
  }

  render() {
    if (!this.props.posts) {
      return <div />;
    }

    // I assume content is something depending on which post is selected?!
    const content = this.state.selected ? <div> Content </div> : null;

    return (
      <ul>
        {this.props.posts.map(post => (
          <div>
            <Checkbox
              checked={this.state.selected === post.id}
              onChange={() => {
                this.setState({
                  selected: post.id,
                });
              }}
            >
              {post.title}
            </Checkbox>
            {content}
          </div>
        ))}
      </ul>
    );
  }
}
于 2018-07-05T10:22:17.123 回答
0

您正在做出反应state.checked以使您的复选框被选中:如果选中一个,它们都将是,因为它们将对相同的状态字段做出反应。

要克服这个问题,试试这个:

  • 给你所有的复选框一个 id 和一个键(如果你不这样做,你应该得到一个警告)。您可以为此使用数组 id,它会起作用。
  • 使状态成为 { checkboxKey: checked } 值的对象

例子

class ColumnName extends Component {
  constructor(props) {
    super(props);
    this.state = { checked: {
      // Initial state ex. 0: true
    } };
  }
  render() {
    if (!this.props.posts) {
      return <div />;
    }

    return (
      <ul>
        {this.props.posts.map((post, id) => (
          <div key={id}>
            <Checkbox
              checked={this.state.checkboxes[i].checked}
              onChange={() => {
                this.setState({
                  checked: !this.checkboxes[i].checked
                });
              }}
            >
              {post.title}
            </Checkbox>
            {content}
          </div>
        ))}
      </ul>
    );
  }
}

export default Search;
于 2018-07-05T10:26:09.517 回答
0

显然所有的帖子都被检查了。这是因为所有 Checkbox 都使用相同的选中值(this.state.checked)。

您可以以不同的方式编辑您的示例...例如,当您在 this.state.checkedPosts 中找到该帖子时,您可以将已检查的帖子保存在您的状态中,并保存在已检查的属性中。

class Test extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
        checkedPosts: [] 
    };

  }

  handleChange(post){
    let index = -1;
    let checkedPosts = this.state.checkedPosts;

    checkedPosts.forEach((elem, idx) => {
        if(elem.title === post.title){
        index = idx;
      }
    })

    if(index === -1){
        checkedPosts.push(post.title);
    }else{
        checkedPosts.splice(index, 1);
    }

    this.setState({checkedPosts:checkedPosts})
  }

  findPostInChecked(post){
    let found = false;

    this.state.checkedPosts.forEach((elem) => {
        if(elem.title === post.title){
        found = true;
      }
   })

    return found;
  }    

  render() {
    const content = this.state.checked ? <div> Content </div> : null;
    return (
      <ul>
        {this.props.posts.map(post => (
          <div key={post.title}>
            <input type="checkbox"
              checked={this.findPostInChecked.bind(post) === true}
              key = {post.title}
              onChange={this.handleChange.bind(this, post)}
            />
            {post.title}
           {content}
          </div>
        ))}
      </ul>
    );
  }
}

ReactDOM.render(
  <Test posts = {[{title:"Hello"}, {title:"Bye"}]}/>,
  document.getElementById('container')
);
于 2018-07-05T10:36:31.770 回答
0

您目前只有一个值checked用于每个CheckBox. 您可以改为跟踪一个对象post是否检查了某个特定项。

例子

class ColumnName extends Component {
  state = { checked: {} };

  toggleChecked = title => {
    this.setState(previousState => {
      const checked = { ...previousState.checked };
      checked[title] = !checked[title];
      return { checked };
    });
  };

  render() {
    if (!this.props.posts) {
      return <div />;
    }

    return (
      <ul>
        {this.props.posts.map(post => (
          <div>
            <Checkbox
              checked={this.state.checked[post.title]}
              onChange={() => this.toggleChecked(post.title)}
            >
              {post.title}
            </Checkbox>
            {this.state.checked[post.title] ? <div> Content </div> : null}
          </div>
        ))}
      </ul>
    );
  }
}
于 2018-07-05T10:23:27.403 回答