我可以在 React.js 中更新组件的 props 吗?

IT技术 javascript reactjs properties
2021-03-05 04:22:56

在开始使用 React.js 之后,它似乎props是静态的(从父组件传入),而state根据事件进行更改。但是,我在文档中注意到对 的引用componentWillReceiveProps,其中特别包含此示例:

componentWillReceiveProps: function(nextProps) {
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}

这似乎意味着,性能可以改变根据的比较组件nextPropsthis.props我错过了什么?props如何更改,或者我是否误解了它的调用位置?

6个回答

一个组件不能更新它自己的 props,除非它们是数组或对象(即使可能,让组件更新它自己的 props 是一种反模式),但可以更新它的 state 和它的孩子的 props。

例如,仪表板speed在其状态中有一个字段,并将其传递给显示此速度的 Gauge 子项。它的render方法就是return <Gauge speed={this.state.speed} />. 当仪表板调用 时this.setState({speed: this.state.speed + 1}),仪表将使用 的新值重新呈现speed

就在这发生之前,componentWillReceiveProps将调用Gauge's ,以便 Gauge 有机会将新值与旧值进行比较。

相反。文件说:“当调用组件正在接收新道具不能调用此方法初始渲染。”
2021-04-21 04:22:56
所以听起来它在 React 组件初始化并接收 props 时被调用一次。一旦创建了组件,道具实际上并不会“改变”。是对的吗?
2021-04-28 04:22:56
谢谢。这个问题来自于最初对 React 的误解,即在重新渲染屏幕(或屏幕的一部分)时会重用组件。
2021-05-02 04:22:56
我来自未来:componentWillReceiveProps现在已经过时了:通过组合所取代getDerivedStateFromPropscomponentDidUpdate
2021-05-06 04:22:56
是的。组件可以侦听事件,并在每次事件触发时更新其状态。
2021-05-13 04:22:56

props

React 组件应该使用 props 来存储可以更改的信息,但只能由不同的组件更改。

状态

React 组件应该使用状态来存储组件本身可以更改的信息。

Valéry 已经提供了一个很好的例子。

@RobBednark 我现在不记得确切的来源了,但可以肯定的是,这是对某本书的句子稍加修改后的真实陈述。
2021-04-17 04:22:56
我发现自己在说:“但我两者都需要?!” 我最终从子组件中重构了一些逻辑,并将其移动到可以作为属性传递给子组件的父组件中。感觉有点不对,但现在运行正常;这就像对 roids 的依赖注入。如果您总是希望子组件表达逻辑并且不想在父组件中使用它的任何地方重新实现它,那么它可能会很烦人。当然,关于这种情况,我还有更多要了解的地方。
2021-05-06 04:22:56
@ali_adravi 是从某处复制的那些引号吗?如果有,参考是什么?或者那些是你的话,你只是将它们格式化为引号以强调?
2021-05-14 04:22:56

当组件的父级使用不同的属性再次渲染组件时,props可能会发生变化。我认为这主要是一种优化,因此不需要实例化新组件。

钩子发生了很多变化,例如componentWillReceiveProps变成了useEffect+ useRef如这个其他 SO 答案所示),但props仍然是只读的,所以只有调用者方法应该更新它。

如果props是数组,则更新props的技巧:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button
} from 'react-native';

class Counter extends Component {
  constructor(props) {
    super(props);
      this.state = {
        count: this.props.count
      }
    }
  increment(){
    console.log("this.props.count");
    console.log(this.props.count);
    let count = this.state.count
    count.push("new element");
    this.setState({ count: count})
  }
  render() {

    return (
      <View style={styles.container}>
        <Text>{ this.state.count.length }</Text>
        <Button
          onPress={this.increment.bind(this)}
          title={ "Increase" }
        />
      </View>
    );
  }
}

Counter.defaultProps = {
 count: []
}

export default Counter
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});
我认为用道具初始化状​​态是反模式,应该避免。这是阅读github.com/vasanthk/react-bits/blob/master/anti-patterns/...的好链接
2021-04-24 04:22:56