React - 如何在render之外的函数内渲染组件并在render之外执行相同的函数?

时间:2018-05-03 11:53:19

标签: javascript reactjs

我在渲染之外有一个函数。该函数返回(有条件地)一个组件,该函数不是在render内部触发,而是在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>
}

5 个答案:

答案 0 :(得分:2)

在构造函数中创建一个名为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});
    }
}

答案 1 :(得分:1)

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

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

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>
          )
      }
}

但是,为了做你想做的事,你实际上会将日期存储在组件的状态中,然后根据渲染方法中的状态渲染数据

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>
          )
      }
}

答案 2 :(得分:1)

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

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 :(得分:0)

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

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

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

答案 4 :(得分:0)

componentWillReceiveProps是React生命周期方法,只要您的React组件接收到父级的prop,就会调用它。可以在那里执行的操作例如更新状态而不是调用返回React组件的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>
}