【问题标题】:How to setState while adding a key value into each array如何在向每个数组中添加键值时设置状态
【发布时间】:2019-03-29 10:24:24
【问题描述】:

我正在尝试在向数组添加键值时设置状态。我已经关注了几个问题,包括这个: How to add a new key value to react js state array?

我无法得到任何答案来应对我的挑战。

我的状态是这样的:

this.state = { jsonReturnedValue: [] }

当 componentDidMount() 我发出 fetch 请求并添加了新状态和 foreach 循环(根据上述问题的说明)

  componentDidMount() {

    let newState = [...this.state.jsonReturnedValue];
    newState.forEach(function(file) {
      file.selected = "false"
    })

    fetch('http://127.0.0.1:8000/api/printing/postcards-printing')
      .then(response => response.json())
      .then(json => {
      this.setState({ jsonReturnedValue: [...this.state.jsonReturnedValue, ...json.printCategory.products] }, () => console.log(this.state));
      })
      .then(this.setState({jsonReturnedValue: newState}, () => console.log("selected added" + this.state) ));
  }

我在想我会再次使用键值对 setState,所以我第三次添加了 .then 但它不起作用。

最终的控制台日志返回:selected added[object Object] 深入挖掘,我发现对象是空的。

编辑:我的目标是通过 api 调用设置状态,同时向每个数组添加“selected: false”的键值。

【问题讨论】:

  • 无论如何,控制台日志看起来都是这样,因为您试图连接一个字符串和一个对象。因此,如果您将日志更改为console.log('selected added', this.state),它仍然返回不正确吗?
  • 这没什么意义。您只想在 fetch 调用完成时设置状态?
  • 我的目标是将 api 调用添加到状态,但还将“selected: false”的键/值添加到每个数组@Jared Smith
  • .then(this.setState 您错误地使用了then,然后需要一个函数回调。例如...then(() => this.setState(....
  • 您应该在问题中描述从 api 返回的数据结构类型以及更新后的状态应该是什么样的

标签: javascript reactjs


【解决方案1】:

componentDidMount 只运行一次,即组件第一次挂载时,即在您的数据调用之前。获取数据并调用setState 后,update lifecycle methods 将运行。

假设您使用的是新版本的 React,您将希望在 getDerivedStateFromProps 中拦截您的状态更改:

getDerivedStateFromProps(props, state) {
  // `state` will be the new state that you just set in `setState`
  // The value returned below will be the new state that the `render`
  // method sees, and creating the new state here will not cause a re-render
  return state.jsonReturnedValue.map((file) => {
    file.selected = "false";
    return file;
  });
}

现在,理想情况下,您实际上并不想在那里执行此操作,而是在获取数据后执行此操作:

fetch('http://127.0.0.1:8000/api/printing/postcards-printing')
      .then(response => response.json())
      .then(json => {
        // NOTE: it's unclear from your post exactly what the data structure is
        // Is it product.file, or is `product` also `file`?
        const products = json.printCategory.products.map((product) => {
          product.file = "selected";
          return product;
        });

        this.setState(
          {
            jsonReturnedValue: [...this.state.jsonReturnedValue, ...products],
          },
          () => console.log(this.state)
        );
      });

【讨论】:

    【解决方案2】:

    应该是这样的

    function addSelectedFalse(array) {
        return array.map(item => ({
            ...item,
            selected: false
        })
    
    fetch('endpoint')
        .then(response => response.json())
        .then(json => this.setState({ jsonReturnedValue: [...addSelectedFalse(this.state.jsonReturnedValue), ...addSelectedFalse(json.printCategory.products] }))
    

    【讨论】:

      【解决方案3】:

      据我了解,您想获取一个产品数组并在设置状态之前将selected: false 添加到每个产品:

      constructor(props) {
          super(props);
          this.state = {
              products: []
          }
      }
      componentDidMount() {
          fetch('http://127.0.0.1:8000/api/printing/postcards-printing')
          .then(response => response.json())
          .then(json => {
              const { products } = json.printCategory;
              for (let i = 0; i < products.length; i++) {
                  products[i].selected = false;
              }
              this.setState({products});
          });
      }
      

      【讨论】:

        【解决方案4】:

        这里有一个想法:

        https://codepen.io/ene_salinas/pen/GYwBaj?editors=0010

          let { Table } = ReactBootstrap;
        
          class Example extends React.Component {
            constructor(props, context) {
              super(props, context);
        
              this.state = {
                  products: []
              }
            }
        
            componentDidMount() {
              console.log('componentDidMount..')
              fetch('https://api.github.com/users/xiaotian/repos')
                .then(response => response.json())
                .then(output => {
                  let products = []
                  for (let i = 0; i < output.length; i++) {
                      products.push({selected:false,name:output[i].name})
                  }
        
                  this.setState({products},() => console.log(this.state))
        
              })
        
            }
        
            render() {
        
                  return(<Table striped bordered condensed hover>
                    <thead>
                      <tr>
                        <th>Selected</th>
                        <th>Name</th>
                      </tr>
                    </thead>
                    <tbody>
                      {this.state.products.map((item, i) => {
                        return (
                            <tr><td><input type="checkbox" checked={item.selected}/></td><td>{item.name}</td></tr>
                        ) 
                      })}
                    </tbody>
                  </Table>)
            }
          }
        
          ReactDOM.render(
            <Example />, 
            document.getElementById('app')
          );
        

        希望能帮到你!

        【讨论】:

          猜你喜欢
          • 2020-12-28
          • 2019-10-21
          • 1970-01-01
          • 2021-11-09
          • 2018-12-30
          • 2021-01-28
          • 1970-01-01
          • 2010-11-17
          • 2017-05-27
          相关资源
          最近更新 更多