简体   繁体   English

将基于 Class 的组件转换为基于功能的组件

[英]transform Class based component to functional based component

guys i wanna convert this code:伙计们,我想转换这段代码:

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = { isLoading: true };
  }

  performTimeConsumingTask = async () => {
    return new Promise((resolve) =>
      setTimeout(() => {
        resolve('result');
      }, 2000)
    );
  };

  async componentDidMount() {
    const data = await this.performTimeConsumingTask();
    if (data !== null) this.setState({ isLoading: false });
  }

  render() {

    if (this.state.isLoading) return <SplashScreen />;

    const { state, navigate } = this.props.navigation;

    return (something)

i wrote this code but it doesn`t work:我写了这段代码,但它不起作用:

const App = () => {
  const [fontLoaded, setFontLoaded] = useState(false);
  const [isTimerOn, setIsTimerOn] = useState(true);

  if (!fontLoaded) {
    return (
      <AppLoading
        startAsync={fetchFonts}
        onFinish={() => setFontLoaded(true)}
      />
    );
  }
  useEffect(async () => {
    const data = await performTimeConsumingTask();
    if (data !== null) setIsTimerOn(false);
  });
  if (isTimerOn) return <SplashScreen />;
  else {
    return (something)

This will show an error: Invariant Violation: Rendered More Hooks than during the previous render.这将显示一个错误: Invariant Violation: Rendered More Hooks than during the previous render.

If I comment the useEffect hook it will run the splashScreen .如果我评论useEffect钩子,它将运行splashScreen Can any one help me in converting it?任何人都可以帮我转换它吗?

There must be no conditional return before using all the hooks, in your case you return before using useEffect .在使用所有钩子之前必须没有条件返回,在您的情况下,您在使用之前返回useEffect

Also useEffect must not run on every render since it sets state in your case.此外useEffect不得在每个渲染上运行,因为它在您的情况下设置了 state。 Since you only want it to run on initial render pass an empty array as the second argument.由于您只希望它在初始渲染时运行,因此将一个空数组作为第二个参数传递。

Also useEffect callback function cannot be async.另外useEffect回调function不能是异步的。

Read more about useEffect hook in the documentation.在文档中阅读有关useEffect挂钩的更多信息。

Check updated code below检查下面的更新代码

const App = () => {
  const [fontLoaded, setFontLoaded] = useState(false);
  const [isTimerOn, setIsTimerOn] = useState(true);

  const performTimeConsumingTask = async () => {
      return new Promise((resolve) =>
         setTimeout(() => {
           resolve('result');
        }, 2000)
   );
  };
  useEffect(() => {
    async function myFunction() {
       const data = await performTimeConsumingTask();
       if (data !== null) setIsTimerOn(false);
    }
    myFunction();
  }, []); // With empty dependency it runs on initial render only like componentDidMount

  if (!fontLoaded) {
    return (
      <AppLoading
        startAsync={fetchFonts}
        onFinish={() => setFontLoaded(true)}
      />
    );
  }
  if (isTimerOn) return <SplashScreen />;
  else {
    return (something)

Pass [] as an argument if you wanted to use this hook as componentDidMount如果您想将此钩子用作componentDidMount ,请将[]作为参数传递

useEffect(async () => {
const data = await performTimeConsumingTask();
if (data !== null) setIsTimerOn(false);
}, []); 

Here is a list of hooks how you can use hooks to replace lifecycle methods这是一个钩子列表,您可以如何使用钩子来替换生命周期方法

https://medium.com/javascript-in-plain-english/lifecycle-methods-substitute-with-react-hooks-b173073052a https://medium.com/javascript-in-plain-english/lifecycle-methods-substitute-with-react-hooks-b173073052a

The Reason for getting an error is your component is rendering too many times and useEffect is also running on each render by passing [] will run the useEffect on first render as it will behave like componentDidMount.出现错误的原因是您的组件渲染次数过多,并且useEffect也在每个渲染上运行,通过传递[]将在第一次渲染时运行useEffect ,因为它的行为类似于 componentDidMount。

Also follow this to make network calls inside useEffect也可以按照这个在useEffect中进行网络调用

https://medium.com/javascript-in-plain-english/handling-api-calls-using-async-await-in-useeffect-hook-990fb4ae423 https://medium.com/javascript-in-plain-english/handling-api-calls-using-async-await-in-useeffect-hook-990fb4ae423

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM