渲染后修改 React 子组件道具

Modify React Child Component props after render

本文关键字:组件 React 修改      更新时间:2023-09-26

这里有一个简单的例子:

copyButton = <SomeReactComponent title="My Button" />
this.clipboard = new Clipboard('button#copy-button');
this.clipboard.on('success', () => { 
    this.copyButton.props.title = "Copied!";
});
render = () => {
    return (
        ...
        { this.copyButton }
        ...
    );
}

使用剪贴板.js,当我按下按钮时,我会将一些文本复制到剪贴板。在成功复制时,我想更改复制按钮的标题以反映这一点。我保留引用的按钮组件已经呈现this.copyButton.props.title显然不起作用,因为组件是不可变的。

那么,我将如何更改按钮上title的值?我知道我可以在父组件中有一个状态属性,但我宁愿避免这样做以保持我的父组件完全无状态。我可以简单地在成功回调中重新分配this.copyButton(我试过但没有运气)?

更笼统地说,父组件应该如何更新其子组件的道具(如果有的话)?使用状态真的是唯一的方法吗?

注意:如果这很重要,我正在使用 ES6。

考虑到您正在尝试更新按钮文本的状态,不以某种形式(在父组件或子组件中)使用 react 状态可能会感觉有点笨拙。 但是,这是可能的。 想到的初始方法是使用React.cloneElement使用所需的title道具创建新版本的copyButton。然后使用 this.forceUpdate 使用更新子组件重新呈现父组件。 像这样:

this.clipboard.on('success', () => { 
    this.copyButton = React.cloneElement(this.copyButton, {
        title: 'Copied!'
    });
    this.forceUpdate();
});

https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement

话虽如此,在这种情况下使用 state 几乎肯定会在可读性和运行时方面更好(克隆元素和强制重新渲染并不便宜)。

对我来说不是很反应。

我想你想做这样的事情:

getInitialState = () => {
  return {
    title: 'Button Title'
  };
};
componentDidMount = () => {
  this.clipboard = new Clipboard(this.refs.copyButton);
  this.clipboard.on('success', () => { 
    this.setState({
      title: 'Copied!'
    })
  });
};
componentWillUnmount = () => {
  // You should destroy your clipboard and remove the listener
  // when the component unmounts to prevent memory leaks
  this.clipboard.destroy();
  // or whatever the comparable method is for clipboard.js
};
render = () => {
  return (
    ...
    <SomeReactComponent ref="copyButton" title={this.state.title} />
    ...
  );
};

最终结果是按钮在初始渲染时安装。然后它的 ref 被传递到componentDidMount(),实例化你的剪贴板和success侦听器。单击按钮时,它会调用this.setState()来更新按钮组件的内部title状态,这会自动触发使用新标题重新呈现组件。

此外,根据 React 文档,如果可以的话,您希望尽量避免使用 forceUpdate()

通常你应该尽量避免使用 forceUpdate(),只在 render() 中读取 this.props 和 this.state。这使您的组件"纯净",并且您的应用程序更简单、更高效。