【问题标题】:Setting State in React for Array of Objects在 React 中为对象数组设置状态
【发布时间】:2018-12-11 03:08:37
【问题描述】:

我是 React 新手,在为一组对象设置状态时遇到问题。我希望每个对象都能够单独反映和“单击”状态。下面是我的代码。

const pictures = [
     {
            photo: 'https://cdn.images.dailystar.co.uk/dynamic/1/photos/755000/620x/cristiano-ronaldo-net-worth-how-much-madrid-player-worth-695569.jpg?r=5c053f491050f',
            id: 0,
            clicked: false
        }, {
            photo: 'https://www.tsn.ca/polopoly_fs/1.912227!/fileimage/httpImage/image.jpg_gen/derivatives/landscape_620/antoine-griezmann.jpg',
            id: 1,
            clicked: false
        }, {
            photo: 'https://e00-marca.uecdn.es/assets/multimedia/imagenes/2018/02/03/15176565269601.jpg',
            id: 2,
            clicked: false
        }, {
            photo: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTqa94bKUtifeRx2kxVEZFgTNx3JjEgD1ymNqRP8k8Au9zmLZiz',
            id: 3,
            clicked: false
        },
]

export default class picRender extends Component {

    state = {
        clicked: false
    }

    handleClick = (event) => {
        if (this.state.clicked === false) {
            this.setState({clicked: true});
            console.log(event.target.getAttribute('data-key') + " state changed to clicked");
            console.log(this.state.clicked);
        } else if (this.state.clicked === true) {
            console.log('THIS HAS BEEN CLICKED!');
        }
    }

    render() {
        return pictures.map(pic => <img
            className="photo"
            data-key={pic.photo}
            key={pic.id}
            src={pic.photo}
            onClick={this
            .handleClick.bind(this)}></img>);
    }
}

每点击一张图片,整个数组的状态就会变为“真”。我不确定如何反映每个单独对象的状态变化。

【问题讨论】:

  • 简单的答案是将img拆分成另一个组件并在点击时添加,这样数组中的每个项目都会有自己的状态

标签: arrays reactjs


【解决方案1】:

您只得到truefalse 的原因是因为当前您只在状态中存储了一个变量clicked。 如果你想单独处理每张图片的状态,你应该有一个状态数组来管理每张图片的点击状态。执行此操作的最简单方法是将初始状态设置为与您的图片数组相同

state = {
        pictures: [
     {
        photo: 'https://cdn.images.dailystar.co.uk/dynamic/1/photos/755000/620x/cristiano-ronaldo-net-worth-how-much-madrid-player-worth-695569.jpg?r=5c053f491050f',
        id: 0,
        clicked: false
    }, {
        photo: 'https://www.tsn.ca/polopoly_fs/1.912227!/fileimage/httpImage/image.jpg_gen/derivatives/landscape_620/antoine-griezmann.jpg',
        id: 1,
        clicked: false
    }, {
        photo: 'https://e00-marca.uecdn.es/assets/multimedia/imagenes/2018/02/03/15176565269601.jpg',
        id: 2,
        clicked: false
    }, {
        photo: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTqa94bKUtifeRx2kxVEZFgTNx3JjEgD1ymNqRP8k8Au9zmLZiz',
        id: 3,
        clicked: false
    },

   ],
 }

现在在您的点击事件中,您需要确定点击了哪张图片,然后更改该特定图片的点击状态。

您可以这样做的一种方法是将您的图像 ID 传递给 handleClick,这样

render() {
        return pictures.map(pic => <img
            className="photo"
            data-key={pic.photo}
            key={pic.id}
            src={pic.photo}
            onClick={this
            .handleClick.bind(this, pic.id)}></img>);
    }

然后在你的handleClick中修改传入id的图片的点击状态

handleClick = (event, id) => {
        //find the picture using the id and change its clicked state
    }

【讨论】:

    【解决方案2】:

    首先,组件名称必须以大写字母开头? PicRender

    在 JSX 中,小写的标签名被认为是 HTML 标签

    一个简单的解决方案,让一个数组包含所有点击的 id

    const pictures = [
      {
        photo: 'https://cdn.images.dailystar.co.uk/dynamic/1/photos/755000/620x/cristiano-ronaldo-net-worth-how-much-madrid-player-worth-695569.jpg?r=5c053f491050f',
        id: 0,
        clicked: false
      }, {
        photo: 'https://www.tsn.ca/polopoly_fs/1.912227!/fileimage/httpImage/image.jpg_gen/derivatives/landscape_620/antoine-griezmann.jpg',
        id: 1,
        clicked: false
      }, {
        photo: 'https://e00-marca.uecdn.es/assets/multimedia/imagenes/2018/02/03/15176565269601.jpg',
        id: 2,
        clicked: false
      }, {
        photo: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTqa94bKUtifeRx2kxVEZFgTNx3JjEgD1ymNqRP8k8Au9zmLZiz',
        id: 3,
        clicked: false
      },
    ]
    
     class PicRender extends React.Component {
    
      state = {
        clicked: []
      }
    
      handleClick = (pic) => {
        if(this.state.clicked.indexOf(pic.id) === -1){
          this.setState((prevState) => ({ clicked: [...prevState.clicked, pic.id] })) // added the id to clicked array
        }else{ // remove the id from clicked array
          this.setState((prevState) => ({ clicked: prevState.clicked.filter(row => row !== pic.id) })) 
        }
      }
    
      render() {
        return pictures.map(pic => <img
          className="photo"
          data-key={pic.photo}
          style={this.state.clicked.indexOf(pic.id) !== -1 ? {border: '5px solid green'} : {}}
          key={pic.id}
          src={pic.photo}
          onClick={this.handleClick.bind(this, pic)}></img>);
      }
    }
    
    ReactDOM.render(<PicRender />, document.getElementById("app"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id='app'></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-11
      • 2021-11-07
      • 2021-08-29
      • 2019-12-05
      • 2019-01-16
      • 1970-01-01
      • 2017-08-17
      • 2017-10-22
      相关资源
      最近更新 更多