javascript - React 函数组件 setTimeout - 多次渲染调用和重新渲染(推荐方法)(多次触发)

标签 javascript reactjs

我有一个通知组件,它应该在几秒钟后自行关闭并调用 onClose 属性:

function Notification(props) {
  console.log("Notification function component called");
  setTimeout(() => {
    props.onClose();
  }, 4000);
  return (
    <div>
      {props.children}
      <button onClick={props.onClose}>Close</button>
    </div>
  );
}

在我的应用程序中,我有一个保存通知对象的状态,并通过它们进行映射。

class App extends React.Component {
  constructor() {
    super();
    this.pushNotification = this.pushNotification.bind(this);
  }
  state = {
    notifications: {}
  };
  pushNotification() {
    const id = uuid();
    const newNotifications = { ...this.state.notifications };
    const date = new Date();
    newNotifications[id] = {
      id,
      date: JSON.stringify(date)
    };
    this.setState({
      notifications: newNotifications
    });
  }
  removeNotification(id) {
    console.log("removeNotification");
    const newNotifications = { ...this.state.notifications };
    delete newNotifications[id];
    this.setState({
      notifications: newNotifications
    });
  }
  render() {
    return (
      <div className="App">
        <button onClick={this.pushNotification}>Push notification</button>
        {Object.keys(this.state.notifications).map(
          (notificationIndexKey, index) => {
            return (
              <Notification
                originalKey={JSON.stringify(index)}
                key={notificationIndexKey}
                onClose={() => {
                  console.log("Notfication fired on close");
                  this.removeNotification(notificationIndexKey);
                }}
              >
                Notification{" "}
                {this.state.notifications[notificationIndexKey].date}
              </Notification>
            );
          }
        )}
      </div>
    );
  }
}

我注意到,如果我在状态下推送多个通知,setTimout 会被初始化多次(这是有道理的,因为每次更新状态时都会调用 render)

我的问题是,您建议如何优化此设置,以便仅调用一次超时。

我尝试过的一种方法是创建一个包含已删除项目的数组,并在调用该属性之前进行检查。

此处的沙箱:https://codesandbox.io/s/6y3my2y2jr

最佳答案

您应该在组件安装后应用该副作用。 目前,您的代码将在渲染时执行此操作。 渲染函数可以被多次调用。

此代码应反射(reflect)正确的更改。

class Notification extends React.Component {
  componentDidMount() {
    setTimeout(this.props.onClose, 4000);
  }
  render() {
    return (
      <div>
       {props.children}
       <button onClick={props.onClose}>Close</button>
      </div>
    );
  }
}

关于javascript - React 函数组件 setTimeout - 多次渲染调用和重新渲染(推荐方法)(多次触发),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55763341/

相关文章:

javascript - react : Should HTML forms be Controlled or Uncontrolled components?

javascript - 与 Cloud Firestore 使用react

javascript - gulp-useref 与几个 html 文件以及如何获取包含在 Assets 中的文件列表

javascript - Jquery asp.net 错误

javascript - Ajax 发送重复的 header

javascript - Semantic-UI 图像属性不适用于语义-ui-react

javascript - React Router 4. 获取事件路由

reactjs - 通过localStorage在reducer中填充initialState

javascript - 访问对象 jquery 中的数组时出现问题

javascript - 使用 lodash debounce 返回 promise