【问题标题】:ReactJS theory render state recursionReactJS 理论渲染状态递归
【发布时间】:2017-10-26 18:35:43
【问题描述】:

我们可以在不重新调用 render() 函数的情况下更改 render() 函数内部的状态变量吗?

当我尝试这个时,它似乎递归地调用 render()。这是最佳做法吗?

例子:

constructor(props) {
       super(props)
       this.state = {
           maxWidth: `${window.innerWidth - 100}px`
       }
    }
    .
    .
    .
    render() {
       const defaultTabCheck = () => {
           if (this.props.tabsProperties.length > 0) {
               this.setState({
                   maxWidth: `${window.innerWidth - 72}px`
               })
           }
       }

       return (
           <span style={‌{ width: this.state.maxWidth }}>
    .

【问题讨论】:

    标签: javascript reactjs jsx


    【解决方案1】:

    来自反应文档

    render() 函数应该是纯函数,即不修改组件状态,每次调用返回相同的结果,不直接与浏览器交互。如果您需要与浏览器交互,请在 componentDidMount() 或其他生命周期方法中执行您的工作。保持 render() 纯净使组件更容易思考。

    对于这个检查,你应该在你的构造函数和componentWillReceiveProps 中进行检查,以便在道具发生变化时进行。

    constructor(props) {
       super(props);
    
       this.state = {
           maxWidth: props.tabsProperties.length > 0 ? `${window.innerWidth - 72}px` : `${window.innerWidth - 100}px`
       }
    }
    
    
    componentWillReceiveProps(nextProps) {
      if (nextProps.tabsProperties.length > 0 && this.props.tabsProperties.length === 0) {
         this.setState({
             maxWidth: `${window.innerWidth - 72}px`
         })
       }
     }
    

    您永远不应该在渲染函数中更新状态,它是一种反模式,即使您使用shouldComponentUpdate 来防止递归,它也不是最佳实践。而是使用 react 提供的生命周期方法,其目的是响应 state/prop 的变化并采取相应的行动。

    https://reactjs.org/docs/react-component.html#render

    【讨论】:

    • 感谢您的回复!假设我们派发一个动作从 redux 中检索数据,然后需要设置状态变量。如何在不调用渲染的情况下设置这些状态变量?有可能吗?
    • 一旦你使用了 redux,你就会拥有一个全局状态(你仍然可以拥有组件状态,但通常你将使用 redux 全局状态)。当您想要更新存储状态而不是检索数据时,您调度操作。如果您希望您的组件从 redux 存储中获取数据,则需要使用 redux 提供的mapStateToProps 功能将特定存储状态映射为组件的道具。
    【解决方案2】:

    您不应该在 render 方法中更新状态。把那个移进去 componentWillReceiveProps 方法代替。欲了解更多信息,请阅读此documentation

    【讨论】:

      猜你喜欢
      • 2020-06-04
      • 2015-08-09
      • 1970-01-01
      • 1970-01-01
      • 2022-11-06
      • 2015-03-11
      • 2020-06-19
      • 1970-01-01
      • 2017-11-11
      相关资源
      最近更新 更多