如何更新使用ReactDOM.render()呈现的React组件的道具

时间:2018-02-07 10:50:05

标签: javascript angular reactjs react-dom

我正在尝试将反应集成到我的angularjs webapp中。

在我的控制器中,我创建了一个组件,该组件最初具有空的数组道具。当应用程序完成初始化时,我想再次更新道具。我是否通过再次致电ReactDOM.render()来执行此操作,还是可以保留对此实例的引用,并执行updateProps(newProps)之类的操作?

这是从我的控制器调用的:

ReactDOM.render(
    <NavBar
        currencyTabs = {[]}
    />, document.getElementById("navbar-root")
);

然后当数据完成加载时,我需要使用完整数组更新currencyTabs ...

我理解如何将组件道具更新从父级更新为子级,但我不知道如何从普通的JS中做到这一点。

2 个答案:

答案 0 :(得分:2)

这里没有任何魔法,你只需要重新渲染它。

只需将渲染包装到函数中,例如:

function renderReactNavbar( tabs = [] ) {
  ReactDOM.render(
    <NavBar
        currencyTabs = { tabs }
    />, document.getElementById("navbar-root")
  );

}

并在加载/更新数据后调用它。

或者,您选择从内部加载数据,从长远来看,这可能是更好的选择。

如果你有内部状态,这可能有点难以处理。您可以考虑转移到仅支持道具的组件(但由于您不能共享反应组件的任何相关代码,因此很难说)

它的外观的一个小例子是

&#13;
&#13;
// the render method, takes a component and props, and renders it to the page
function renderComponent( component, props ) {
  const target = document.querySelector('#container');
  ReactDOM.render( React.createElement( component, props ), target );
}

// gets the tabs from the input field, splits based on ,
function getTabsFromInput() {
  return document.querySelector('#tabs').value.split(',');
}

// small presentational component, shows the tabs and redirects selection changes through a callback
const Tabs = ({ tabs, selectedTab, onSelectionChanged }) => {
  return tabs && <div>{ tabs.map( (tab, key) => {
    return <h1 key={key} className={classNames( { 'active': key === selectedTab } ) } onClick={ () => onSelectionChanged( key ) }>{ tab }</h1>;
  } ) }</div>;
};

// some initiations
window.addEventListener('load', function() {
  // keep a local variable with the data
  let defaultProps = {
    onSelectionChanged: updateSelection,
    selectedTab: 0,
    tabs: getTabsFromInput()
  };

  // handles selection changes
  function updateSelection( newTab ) {
    defaultProps = {...defaultProps, selectedTab: newTab };
    renderComponent( Tabs, defaultProps );
  }

  // adds an event listener for click events to initiate tab changes
  document.querySelector('#updateTabs').addEventListener('click', function() {
    defaultProps = {...defaultProps, tabs: getTabsFromInput() };
    // render on update
    renderComponent( Tabs, defaultProps );
  });

  // initial render
  renderComponent( Tabs, defaultProps );
});
&#13;
.active {
  background-color: blue;
}
&#13;
<script id="react" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.js"></script>
<script id="react-dom" src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.js"></script>
<script id="classnames" src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.5/index.js"></script><div id="container"></div>
<input type="text" value="tab1,tab2" id="tabs" />
<button id="updateTabs" type="button">Update tabs</button>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您的NavBar组件具有可以使用生命周期方法更新的状态。没有你的代码,很难确定,但我认为你想要像

这样的东西
class NavBar extends Component {
  state: { currencyTabs: [] }

  componentWillRecieveProps(nextProps) {
    if (this.props.currencyTabs !== nextProps.currencyTabs) {
      this.setState({ currencyTabs: nextProps.currencyTabs })
    }
  }

  render() {
    return (
      <div>
        {this.state.currencyTabs.map(button => (
          <span>{currency}</span>
        )}
      </div>
    )
  }
}

当您的ReactDOM.render方法更改currencyTabs道具时,该组件将重新渲染并且将反映更改