如何在向每个数组添加键值的同时设置状态

时间:2018-10-24 22:07:30

标签: javascript reactjs

我试图在将键值添加到数组时设置状态。我关注了包括此问题在内的几个问题: How to add a new key value to react js state array?

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

我的状态是这样的:

this.state = { jsonReturnedValue: [] }

当componentDidMount()发出获取请求并添加新状态和一个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”。

4 个答案:

答案 0 :(得分:2)

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)
        );
      });

答案 1 :(得分:0)

应该可能是这样的

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] }))

答案 2 :(得分:0)

据我所知,您想获取一个产品数组,并在设置状态之前将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});
    });
}

答案 3 :(得分:0)

这里有个可行的想法:

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')
  );

希望能帮助您!