尝试通过useEffect挂钩实现此功能

时间:2020-01-18 18:31:43

标签: javascript reactjs react-hooks react-functional-component

我只是在玩React钩子,以更好地理解它,并最终解决了下面提到的这个用例。

所以我想要的是Sample Component在第一个渲染上显示 text 的大写值,否则显示它接收到的确切文本值

现在要实现这一点,我必须使用两个useEffect

  1. 要使第一个渲染的 text 值大写
  2. 在道具更改/更新时更新 text

使用这种方法我意识到的状态(我认为)将被更新两次,即通过两个useEffect挂钩。另外,我必须保持效果钩的顺序相同,因为它们按顺序运行,并且更改顺序将使第一个渲染吐出 text

的普通大小写。

实现此目标的另一种(更好)方法是什么?

const { useState, useEffect } = React;
const { render } = ReactDOM;

const upperCase = str => str.toUpperCase();

const Sample = ({ text }) => {
  const [state, setState] = useState(upperCase(text));
  
  useEffect(() => {
    setState("text");
  }, [text]);
  
  useEffect(() => {
    setState(upperCase(text));
  }, []);

  return (
    <div>
      <p>{state}</p>
    </div>
  );
};

const App = () => {
  const [state, setState] = useState("Sample");
  return (
    <div>
      <Sample text={state} />
      {state}
      <input value={state} onChange={e => setState(e.target.value)} />
      <h3>App Component</h3>
    </div>
  );
};

render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script>

2 个答案:

答案 0 :(得分:3)

我相信更好的选择是这样做:

const Sample = ({ text }) => {
  const ref = useRef(false);

  useEffect(() => {
    ref.current = true;
  }, [text]);

  return (
    <div>
      <p>{ref.current ? text : text.toUpperCase()}</p>
    </div>
  );
};

通过检查值ref.current,您将知道这是否是第一个渲染。

答案 1 :(得分:-1)

根据这样的文本更改,仅执行1 useEffect:

const Sample = ({ text }) => {
  const [state, setState] = useState(upperCase(text));

  useEffect(() => {
    if (text !== state) setState(upperCase(text));
  }, [text]);

  return (
    <div>
      {console.log(state)}
      <p>{state}</p>
    </div>
  );
};