React:如何更新根组件的道具

时间:2018-06-11 03:37:55

标签: reactjs

我在dom上安装了一个React根组件,它从初始页面加载中接收JSON作为props。

在API调用之后,我想更新该JSON。

我不知道这里最好的模式是什么,因为搜索Update props on root component给了我很少的结果,#1页实际上是Preact lib(不是React)。

我应该将JSON克隆到constructor中我的根组件的状态,这允许我在API调用后通过根组件本身的this.setState更改它吗?

我知道的另一个选项是再次调用ReactDOM.render,但这看起来更复杂:即使是艰难的我也可以传递所有它的当前道具而新的那个{...this.props, propsThatWasUpdated },我假设调用{{ 1}}将重置组件的内部状态,这是我不想要的。

3 个答案:

答案 0 :(得分:2)

最好能提供一些代码。无论如何,我建议,

  1. 在componentDidMount方法中调用api。
  2. 从api获取数据并使用数据(setState())
  3. 设置状态
  4. 将此状态指定为组件的道具
  5. 因此,自状态发生变化后,当数据来自带有新数据的api时,反应会重新呈现您的子组件。

答案 1 :(得分:0)

如果你的组件通过props接收JSON数据,那么玩数据的好地方就是生命周期方法componentWillReceiveProps:

componentWillReceiveProps(newProps) {
    if(this.props !== newProps) {
      // update data or store it in state
    }
}

答案 2 :(得分:0)

I assume the call to ReactDOM.render() will reset the component's inner state, which I don't want.

Actually, this is not the case. At least for the latest version of React.

According to the ReactDOM documentation:

If the React element was previously rendered into container, this will perform an update on it and only mutate the DOM as necessary to reflect the latest React element.

So, if you really need to update the props of the root React application component this is a way to go. I would suggest to use this approach only when React is integrated into existing JavaScript application or into some other framework (like Angular).

Here's the helper class I've created to integrate React component into any application:

import * as React from 'react';
import * as ReactDOM from 'react-dom';


export class ReactHandler<PropsType> {

  private container: HTMLElement;
  private props: any;


  constructor(private component: typeof React.Component) {
  }

  public get isMounted(): boolean {
    return !!this.container;
  }

  public mount(container: HTMLElement, props?: PropsType) {
    this.ensureUnmounted();
    this.container = container;
    this.props = props;
    this.render();
  }

  public unmount() {
    this.ensureMounted();
    ReactDOM.unmountComponentAtNode(this.container);
    this.container = null;
  }

  public updateProps(props: PropsType) {
    this.ensureMounted();
    Object.assign(this.props, props);
    this.render();
  }


  private render() {
    const componentInstance = React.createElement(this.component, this.props);
    ReactDOM.render(componentInstance, this.container);
  }

  private ensureMounted() {
    if (!this.isMounted) {
      throw new Error(`The component "${this.component.name}" is not mounted`);
    }
  }

  private ensureUnmounted() {
    if (this.isMounted) {
      throw new Error(`The component "${this.component.name}" is already mounted`);
    }
  }

}

Call it like this:

// Instantiate the helper
// "Greeter" is a component you are trying to mount
const reactHandler = new ReactHandler<GreeterProps>(Greeter);

// Mount
reactHandler.mount(containerDomElement);

// Update props (partially)
reactHandler.updateProps({ foo: 'foo' });

// Do not forget to unmount or you will cause memory leak!
reactHandler.unmount();
相关问题