show - hide component with hook function 只工作一次

show - hide component with hook function works only one time

我正在尝试显示和隐藏一个功能组件,它只在加载时有效。隐藏后它不再显示。我明白,我使用 functional component 的方式不对。

请问有人给我推荐正确的方法吗?

这是我的代码:(index.tsx)

import React, { Component, useState } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';

const App = () => {
  const [isBoolean, setBoolean] = useState(false);

  const showComponent = () => {
    setBoolean(true);
  };

  return (
    <div>
      <Hello isBoolean={isBoolean} />
      <p>Start editing to see some magic happen :)</p>
      <button onClick={showComponent}>Show hello component</button>
    </div>
  );
};

render(<App />, document.getElementById('root'));

你好组件:

import React, { useEffect, useState } from 'react';

export default ({ isBoolean }: { isBoolean: boolean }) => {
  const [isShow, setIsShow] = useState(false);

  useEffect(() => {
    setIsShow(isBoolean);
  }, [isBoolean, setIsShow]);

  const shufler = () => {
    setIsShow(false);
  };

  if (!isShow) {
    return null;
  }

  return (
    <div>
      <p>hi {JSON.stringify(isShow)}</p>
      <button onClick={shufler}>Hide Component</button>
    </div>
  );
};

Live Demo

无需维护 child 组件中 prop 的派生状态(Hello),您可以将回调和状态作为来自 parent 组件的 props 传递(index) 到 child.

问题原因:

隐藏组件 isShow 设置为 false 后,isBoolean 仍然为 true。所以下次我们点击show按钮的时候isBoolean没有变化,仍然是不会触发[=40=中的useEffect ]isShow 从未设置为 true,这导致 child 为 return null。

index.tsx

import React, { Component, useState } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';

const App = () => {
  const [isBoolean, setBoolean] = useState(false);

  const showComponent = () => {
    setBoolean(true);
  };

  const hideComponent = () => {
    setBoolean(false);
  }



  return (
    <div>
      <Hello isBoolean={isBoolean} hideComponent={hideComponent} />
      <p>Start editing to see some magic happen :)</p>
      <button onClick={showComponent}>Show hello component</button>
    </div>
  );
};

render(<App />, document.getElementById('root'));

Hello.tsx

 import React, { useEffect, useState } from 'react';

export default ({ isBoolean, hideComponent }: { isBoolean: boolean }) => {
  if (!isBoolean) {
    return null;
  }

  return (
    <div>
      <p>hi {JSON.stringify(isBoolean)}</p>
      <button onClick={hideComponent}>Hide Component</button>
    </div>
  );
};

解释您的代码为何不起作用:

useEffect(() => {
    setIsShow(isBoolean);
}, [isBoolean, setIsShow]);
  • 最初当您在 parent 中将 isBoolean 设置为真时,此 useEffect 在 child 运行 中也是如此
  • 然后从 child 组件
  • 中将 isShow 设置为 false
  • 然后你再次在 parent 组件中将 isBoolean 设置为 true,但是对于上面的 useEffectisBoolean 现在是 true,它也是 true在之前的渲染中,所以它不再 运行。

因此,如果可能的话,无需在 child 中复制 isBoolean 状态,只需将其作为 props 传递并直接使用,就像在其他答案中一样。