【问题标题】:How to store all array values into a single React state?如何将所有数组值存储到单个 React 状态?
【发布时间】:2021-03-26 13:45:25
【问题描述】:

我有一个配置文件,其中包含一个从 redux 获取数据的数组

"datapath": [
  "common.registration.rgsnInfoRs[0].value",  // street name
  "common.registration.rgsnInfoRs[1].value",  // city
  "common.registration.rgsnInfoRs[2].value",  // state
  "common.registration.rgsnInfoRs[3].value"   // zip code
]

在我的 react 组件中,当我尝试从这个数组中渲染数据时,它只返回邮政编码的数据。如何让我的组件在我的渲染方法中渲染所有索引数据?

constructor(props) {
  super(props);
  this.state = {
    // data: '',
    data: []
  }
}
componentDidMount(){
  if(_.get(this.props, 'datapath')){
    _.map(this.props.datapath, (item, i) => {
      let data=_.get(this.props.state,`i`);
      this.setState({data})
    })
  }
}

// static getDerivedStateFromProps(props, state) {
//   if(_.get(props, 'datapath')){
//     _.map(props.datapath, (item, i) => {
//       let data=_.get(props.state,item);
//       state.data = data;
//     }) 
//   }
// }


static getDerivedStateFromProps(props, state) {
    if(_.get(props, 'datapath')){
      _.map(props.datapath, (item, i) => {
        let data=_.get(props.state,item);
        this.setState((prevState) => {
          return { data: [...prevState.data, data] }
         });
      })
    }
  }

render() {
  const {type, label} = this.props;
  return (
    type === "grid" ? (
      <Grid.Column style={style}>
        <strong>{label ? `${label}:` : null}</strong> {this.state.data}
      </Grid.Column>
    ) : (
      null
    )
  )
}

【问题讨论】:

  • this.props.state 的数据类型是什么?
  • @fyasir 感谢您的回复。状态的数据类型是字符串,但我将其更改为数组。我会更新我的帖子。

标签: javascript reactjs redux lodash


【解决方案1】:

this.state.data 的初始数据类型是数组。但在下一行中,它获取项目的值(在本例中,它是街道名称、城市、州或邮政编码)。这些值是字符串类型并覆盖从数组到字符串的this.state.data 数据类型。

let data=_.get(props.state, `i`); // This is incorrect

您应该在状态数据中附加值,而不是在componentDidMount 中赋值

componentDidMount() {
  if(_.get(this.props, 'datapath')){
    _.map(this.props.datapath, (item, i) => {
       let data=_.get(this.props.state,`i`);
       this.setState((prevState) => {
          return { data: [...prevState.data, data] }
        });
    })
  }
}

现在让我们看看getDerivedStateFromProps 函数。这是一个静态函数,您不能在静态函数中使用this。根据react docs,该函数返回更新后的状态。

static getDerivedStateFromProps(props, state) {
const newData = [];
if(_.get(props, 'datapath')) {
  _.map(props.datapath, (item, i) => {
    let data=_.get(props.state,item);
    newData.push(data);
  });
  return { data: newData };
}

}

【讨论】:

  • 那行不通。它打破了页面。我放对地方了吗? static getDerivedStateFromProps(props, state) { if(_.get(props, 'datapath')){ _.map(props.datapath, (item, i) =&gt; { let data=_.get(props.state,item); this.setState((prevState) =&gt; { return { data: [...prevState.data + data] } }); }) } }
  • 让我也将它添加到帖子中以获得更好的可见性。
  • @Shaun 你在控制台遇到什么错误?
  • 我看到以下错误Uncaught TypeError: Cannot read property 'setState' of undefined
  • 你试图在静态函数中使用 this.setState :) 在getDerivedStateFromProps 你应该返回状态而不是使用 this.setState
【解决方案2】:

我认为您没有提出正确的问题。在 state 中存储 props 中的数据通常是一个坏主意,因为它可能导致数据过时和过时。如果你已经可以从 props 访问它,那么你不需要让它处于状态。

您的组件收到一个 prop state,它是一个对象和一个 prop datapath,它是一个用于访问该 state 上的属性的路径数组。这已经很奇怪了,您应该研究通过选择器函数访问 redux 数据的更好模式。

但是如果我们不能改变它,我们至少可以改变这个组件。您可以使用一行代码将路径数组转换为值数组:

const data = this.props.datapath.map( path => _.get(this.props.state, path) );

组件中的所有状态和生命周期都是不必要的。可以简化为:

class MyComponent extends React.Component {
  render() {
    const { type, label = "", state, datapath = [] } = this.props;
    const data = datapath.map((path) => _.get(state, path, ''));
    return type === "grid" ? (
      <Grid.Column style={style}>
        <strong>{label}</strong> {data.join(", ")}
      </Grid.Column>
    ) : null;
  }
}

【讨论】:

  • 这太棒了!非常感谢您的分享。
【解决方案3】:

我认为,当您遍历数据并设置状态时,您正在覆盖该状态中已经存在的旧数据。

可能您必须包含以前的数据以及在其中设置新数据,就像这样。

this.setState({data : [...this.state.data, data]})

【讨论】:

  • 我尝试了上述行,但没有奏效。它打破了页面。
猜你喜欢
  • 2021-04-18
  • 1970-01-01
  • 2018-10-21
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 2022-12-19
  • 2018-07-08
  • 1970-01-01
相关资源
最近更新 更多