【问题标题】:Assigning an array as a react component state property?将数组分配为反应组件状态属性?
【发布时间】:2017-11-29 21:26:00
【问题描述】:

尝试将非空数组设置为组件状态属性时(在初始化时,在组件构造函数中),例如:

this.state = { results: ['apple','orange'] } //in the component constructor

控制台返回此错误:

在这种环境下,assign 的来源必须是一个对象。这 错误是一种性能优化,不符合规范

如果数组是空的,那可以工作(但是一旦你尝试重新分配一个非空数组,它就会出错)

所以这行得通:

this.state = { results: [] }  //in the component constructor

直到你这样做

this.setState({results: ['apple','orange'] }) //in a component function

此时会返回上一个错误...

我不明白。 javascript 数组不应该也是对象类型,因此可以用作状态属性值吗?

我在 Android 设备上使用最新的 react-native 版本 (0.45.1) 对其进行了测试。

state.results 对象仅在这样的列表视图中使用:

   const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 })

  render () {
    return (

    <ListView 
              style={{position: 'absolute', width: 100, backgroundColor: 'white', zIndex: 3}}
              keyboardShouldPersistTaps='always'
              initialListSize={15}
              enableEmptySections={true}
              dataSource={ds.cloneWithRows(this.state.results)}
              renderRow={(rowData, sectionId, rowId, highlightRow) =>
                <RowWrapper styles={styles.rowWrapper} >
                  <TouchableOpacity
                    activeOpacity={0.5}
                    onPress={() => {this.onItemPress(this.state.results[rowId])}}
                  >
                    <Text style={styles.rowText}>{rowData}</Text>
                  </TouchableOpacity>
                </RowWrapper>
              }
            />
   )
  }

    class RowWrapper extends Component {
      constructor (props) {
        super(props)
        this.defaultTransitionDuration = 500
        this.state = {
          opacity: new Animated.Value(0)
        }
      }
      componentDidMount () {
        Animated.timing(this.state.opacity, {
          toValue: 1,
          duration: this.defaultTransitionDuration
        }).start()
      }
      render () {
        return (
          <TouchableWithoutFeedback>
            <Animated.View style={{...this.props.styles, opacity: this.state.opacity }}>
              {this.props.children}
            </Animated.View>
          </TouchableWithoutFeedback>
        )
      }
    }

【问题讨论】:

  • 嘿,你能发布更多代码吗?您发布的内容应该可以正常工作,因此我认为该错误是由于您的代码中的其他内容造成的。顺便说一句,您是在任何地方使用 Object.assign 还是在使用 this.state.results 的地方发布。谢谢
  • @MattAft 。我用我正在使用 this.state.results 的部分代码编辑了我的第一篇文章。我不在任何地方使用 Object.assign 并且 listview 是我的代码中唯一读取 this.state.results 的部分(否则它只出现在组件构造中 this.state = { results: [] } 和组件函数,它被 this.setState({results : ['apple','orange']}) 覆盖,但它是问题发生的地方......)

标签: android reactjs react-native state setstate


【解决方案1】:

你不应该改变状态。 而不是做

this.setState({results: ['apple','orange'] })

你应该这样做

var resultsArr = this.state.results.slice();
var newResults = ['apple','orange'];
resultsArr.concat(newResults); or resultsArr.push(newResults);
this.setState({results: resultsArr })

【讨论】:

  • 我没有直接改变状态,因为我调用 this.setState() 应该将传入参数的内容与组件状态合并...我看不出有什么区别在做之间: var newResults = ['apple','orange']; this.setState({results: newResults }) 直接和 var resultsArr = this.state.results.slice(); var newResults = ['apple','orange']; resultsArr.concat(newResults); this.setState({results: resultsArr }) 除了制作一个不必要的空临时数组...
  • 无论如何,您的代码无法解决问题,正如我所说,如果我也直接使用非空数组初始化状态属性,则会发生错误。所以这与改变状态无关......
  • 你能试试这个吗:this.setState({ results: [this.state.results.concat['apple', 'orange'] ] })with es6 this.setState({ results: [...this.state.results, ...['apple', 'orange'] ] })
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 2017-03-31
  • 2018-07-01
  • 2019-03-27
相关资源
最近更新 更多