javascript - 我可以在功能组件中使用什么来实现与 componentDidMount 相同的行为?

标签 javascript reactjs typescript react-hooks use-effect

我的 UI 工作正常,直到它使用类组件。现在我将其重构为一个功能组件。

我必须根据从 API 处理程序收到的数据加载 UI。我的用户界面将反射(reflect)房间内相机的状态。每次从房间打开或关闭摄像头时,我都应该从 API apiToGetCameraState 接收新状态。

我希望 registerVideoStateUpdateHandlerWrapper 中存在的 console.log 首次在 UI 加载时打印,并在每次视频状态更改时加载房间。但是,第一次加载 UI 时它不起作用。

这就是我的组件的样子:

const Home: React.FunctionComponent<{}> = React.memo(() => {
  const [video, setToggleVideo] = React.useState(true);

  const registerVideoStateUpdateHandlerWrapper = React.useCallback(() => {
    apiToGetCameraState(
      (videoState: boolean) => {
        // this log does not show up when the UI is loaded for the first time
        console.log(
          `Video value before updating the state: ${video} and new state is: ${videoState} `
        );
        setToggleVideo(videoState);
      }
    );
  }, [video]);

  React.useEffect(() => {
    //this is getting called when the app loads
    alert(`Inside use effect for Home component`);
    registerVideoStateUpdateHandlerWrapper ();
  }, [registerVideoStateUpdateHandlerWrapper ]);

  return (
      <Grid>
        <Camera
          isVideoOn={video}
        />
      </Grid>
  );
});

当我的代码位于类组件中时,这工作正常。这就是类组件的样子。

class Home extends Component {
    
    registerVideoStateUpdateHandlerWrapper = () => {
        apiToGetCameraState((videoState) => {
            console.log(`ToggleVideo value before updating the state: ${this.state.toggleCamera} and new state is: ${videoState}`);
            this.setStateWrapper(videoState.toString());
        })
    }
    setStateWrapper = (toggleCameraUpdated) => {
        console.log("Inside setStateWrapper with toggleCameraUpdated:" + toggleCameraUpdated);
        this.setState({
            toggleCamera: (toggleCameraUpdated === "true" ) ? "on" : "off",
        });
    }
   
    constructor(props) {
        super(props);
        this.state = {
            toggleCamera: false,
        };
    }
    componentDidMount() {
        console.log(`Inside componentDidMount with toggleCamera: ${this.state.toggleCamera}`)
        this.registerVideoStateUpdateHandlerWrapper ();   
    }
    render() {
      return (
        <div>
          <Grid>
            <Camera isVideoOn={this.state.toggleCamera} />
          </Grid>
     );
  }
}

我尝试了什么?

  1. 我尝试删除 registerVideoStateUpdateHandlerWrapper 函数中的 useCallback 以及 React.useEffectregisterVideoStateUpdateHandlerWrapper 中的依赖项数组>。它的行为是一样的
  2. 我尝试更新 React.useEffect 以将 registerVideoStateUpdateHandlerWrapper 的代码包含在其中,但仍然没有成功。

最佳答案

registerVideoStateUpdateHandlerWrapper() 移动到 useEffect() 回调中,如下所示。如果你想在状态改变时记录之前的状态,你应该使用 functional update避免capturing the previous state through the closure :

const Home = () => {
  const [video, setVideo] = useState(false);

  useEffect(() => {
    console.log('Inside useEffect (componentDidMount)');

    const registerVideoStateUpdateHandlerWrapper = () => {
      apiToGetCameraState((videoState) => {
        setVideo((prevVideo) => {
          console.log(`Video value before updating the state: ${prevVideo} and new state is: ${videoState}`);
          return videoState;
        });
      });
    };

    registerVideoStateUpdateHandlerWrapper();
  }, []);

  return (
    <Grid>
      <Camera isVideoOn={video} />
    </Grid>
  );
};

当您不再实际需要记录以前的状态时,您应该将 registerVideoStateUpdateHandlerWrapper() 简化为:

const registerVideoStateUpdateHandlerWrapper = () => { 
  apiToGetCameraState((videoState) => {
    setVideo(videoState);
  });
};

关于javascript - 我可以在功能组件中使用什么来实现与 componentDidMount 相同的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66253812/

相关文章:

javascript - 源码和 "inspect element"的区别

javascript - 当用户在 jquery 中按下回车键时,将 <br/> 添加到 p TAG contenteditable

reactjs - 如何将Threejs连接到React?

javascript - React hook 状态对于几个相同的事件具有不同的值

javascript - 添加数组中对象的所有匹配值 (Javascript) (Angular)

javascript - Node.js 重定向到 ip :port based on the used domain name

javascript - 为什么 crockford 在他的 json_parse 函数中创建这种类型的错误函数?

javascript - TypeScript+React 突然出现不兼容的 Props 错误

html - Ionic 3获取点击项目的索引

typescript - 函数返回类型取决于是否传递可选参数