【问题标题】:React - How to render components inside a function outside of render plus execute same function outside of render?React - 如何在渲染之外的函数内渲染组件并在渲染之外执行相同的函数?
【发布时间】:2018-05-03 11:53:18
【问题描述】:

我有一个渲染之外的功能。该函数(有条件地)返回一个组件,该函数不是在渲染内部触发,而是在 componentWillReceiveProps 内部触发(由于其他事实,这是必要的)。 我的问题是函数最终没有返回组件,我不知道为什么。当我在渲染中调用该函数时,它可以工作,但我不能这样做,因为我必须在 componentWillReceiveProps 中调用它。有任何想法吗?谢谢!!

class App extends React.Component {
  componentWillReceiveProps(nextProps) {
    if (nextProps.user != this.props.user) {
      this.getData(nextProps.user)
    }
  }

  getData() {
    if (...) {
      return <Child />
    }
  }

  render() {
    return (
      <div>{this.getData}</div>
    );
  }
}

const Child = () => {
  return <h1>Hello</h1>
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    在构造函数中创建一个名为data的状态,如下:

    constructor(props){
        super(props);
        this.state={data:""};
    }
    

    现在,{this.getdata}render(){this.state.data}

    同样替换componentWillReceiveProps如下:

    componentWillReceiveProps(nextProps) {
        if (nextProps.user != this.props.user) {
            var newdata = this.getData(nextProps.user)
            this.setState({data:newdata});
        }
    }
    

    【讨论】:

    • 谢谢。所以我的 getData 函数只返回真或假。如果它是真的,我会渲染子组件,如果是假的,我会渲染另一个。现在我可以在我的渲染函数中做: {this.data==true ? }。除了根据我的状态变量值在渲染中渲染 Child 等之外别无其他方法是否正确?
    • @2018code2018 您好,抱歉,我没有得到您的要求。你能告诉我你最初想要渲染什么以及何时收到道具。还要说明您是否要完成其他任何事情或有疑问
    【解决方案2】:

    因为除了render 之外,您不能从其他钩子返回children,您需要将它们保持在一个状态:

    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          someChildren: null
        };
      }
    
      componentWillReceiveProps(nextProps) {
        if (nextProps.user != this.props.user) {
          this.setState({ someChildren: this.getData(nextProps.user) });
        }
      }
      getData() {
        if (...) {
          return <Child />;
        }
        return null
      }
      render() {
        return <div>{this.state.someChildren}</div>;
      }
    }
    

    【讨论】:

      【解决方案3】:

      当您的组件收到新的道具时,它会自动重新渲染,如下所示,您应该让您的组件重新渲染并更新:

      class App extends React.Component {
        getData: () => {
          if (...) {
            return <Child />
          }
          return null;
        };
      
        render() {
          return (
            <div>{this.getData()}</div>
          );
        }
      }
      

      【讨论】:

      • 由于其他问题,我不能在渲染中调用该函数,但我想没有其他方法,但不要在我的函数中渲染组件
      • 也许你应该解决“其他问题”,不是吗?
      【解决方案4】:

      componentWillReceiveProps 是 React 生命周期方法,一旦你的 React 组件收到父级的 prop,就会调用它。可以在那里执行的操作例如更新状态,而不是调用返回 React Component 的 getDate 方法。

      一个可能的实现可能是:

      class App extends React.Component {
      
        getData() {
          const { user } = this.props;
          return user ? <Child /> : <div />
        }
        render() {
            return (
                <div>
                  {this.getData()}
                </div>
            )
        }
      }
      
      const Child = () => {
        return <h1>Hello</h1>
      }
      

      【讨论】:

        【解决方案5】:

        您只能在渲染中返回 JSX 数据,而不能在要渲染的其他生命周期函数中返回。 render 方法也是纯的,所以对于相同的输入,它返回相同的输出,因此 react 能够通过维护一个虚拟 dom 来正确优化相同的性能,所以你只需编写

        class App extends React.Component {
              getData() {
                if (...) {
                    return <Child />
                }
              }
              render() {
                  return (
                      <div>
                        {this.getData()}
                      </div>
                  )
              }
        }
        
        const Child = () => {
            return <h1>Hello</h1>
        }
        

        如果您使用React.PureComponent 进一步优化,它也会产生相同的效果,以便在道具更改时调用渲染。 React.PureComponent 实现了 shouldComponentUpdate 的浅层 prop 和状态比较。

        class App extends React.PureComponent {
              componentWillReceiveProps(nextProps) {
                 if (nextProps.user != this.props.user) {
                 this.getData(nextProps.user)
                 }
              }
              getData() {
                if (...) {
                    return <Child />
                }
              }
              render() {
                  return (
                      <div>
                        {this.getData()}
                      </div>
                  )
              }
        }
        

        无论如何,你实际上是将日期存储在组件的 state 中,然后在 render 方法中根据 state 渲染数据

        class App extends React.Component {
              constructor(props) {
                 super(props);
                 this.state {
                     data: this.getData(props)
                 }
              }
              componentWillReceiveProps(nextProps) {
                 if (nextProps.user != this.props.user) {
                    this.getData(nextProps.user)
                 }
              }
              getData(props) {
                if (...) {
                    const newData;
                    // update newData based on receivedProps here
                    // store the data in state
                    this.setState({data: newData});
                }
                return [];
              }
              render() {
                  return (
                      <div>
                        {this.state.data.map((obj) => return <Child data={obj}/>)}
                      </div>
                  )
              }
        }
        

        【讨论】:

        • 由于其他问题,我无法在渲染内部调用该函数。我不认为我可以使用 React.PureComponent,因为我的组件有更多代码,我不想影响它。我想我只是不能在渲染之外渲染组件。
        • 什么问题导致你没有在render中调用函数,如果你的getData是纯的,你可以在render中使用它,但是另一种方法是实际将数据存储在状态中,然后在基于状态的渲染中渲染 JSX
        猜你喜欢
        • 2018-09-23
        • 2020-01-22
        • 2020-10-03
        • 1970-01-01
        • 2019-09-28
        • 1970-01-01
        • 2018-12-14
        相关资源
        最近更新 更多