如何保持调用useEffect方法的反应直到有条件为止?

时间:2019-07-07 20:02:23

标签: javascript reactjs react-hooks react-16

我正在尝试基于数组更新textarea的值。 从textToEdit值,单击显示值按钮,我试图提取 textToEdit的每一行都将更新视图,然后在调用使用效果时执行其他逻辑,然后再次调用setstate来更新视图,然后执行其他逻辑。

换句话说, 将每行追加到textarea并调用一个函数,然后追加另一行,调用一个函数,直到所有行都被追加。

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

function App() {
  const [theme, setTheme] = useState('light');
  const [language, setLanguage] = useState('javascript');
  const [isEditorReady, setIsEditorReady] = useState(false);
  const valueGetter = `
    some random text line 1
    some random text line 2
    some random text line 3
    some random text line 4
  `
  const [code, setCode] = useState(valueGetter);
  const counts = useRef(0);
  const totalCount = useRef(0);

  useEffect(() => {
    console.log('counts.current', counts.current, totalCount.current);
    if (counts.current > 0 && counts.current < totalCount.current) {
      counts.current = counts.current + 1;
      const stringArr = valueGetter.split(/\n/g);
      const newString = stringArr.splice(0, counts.current).join('\n');
      // need to do someother logic
      setCode(newString);
    }
  }, []);

  function handleShowValue() {
    console.log(valueGetter);
    counts.current = 1;
    const stringArr = valueGetter.split(/\n/g);
    totalCount.current = stringArr.length;
    const newString = stringArr.splice(0, counts.current).join('\n');
    setCode(newString);
  }

  function toggleTheme() {
    setTheme(theme === 'light' ? 'dark' : 'light');
  }

  function toggleLanguage() {
    setLanguage(language === 'javascript' ? 'python' : 'javascript');
  }

  return (
    <>
      <button onClick={handleShowValue} disabled={!isEditorReady}>Show value</button>

      <textarea
         value={code}
      />
    </>
  );
}

export default App;

这只是添加一行。我究竟做错了什么? https://codesandbox.io/s/react-usestate-hook-example-v59wc

1 个答案:

答案 0 :(得分:-1)

在这里,您可以更改代码以确保正确使用useEffect。计数已更改为useState。阅读材料:https://reactjs.org/docs/hooks-effect.html

import React, { useState, useRef, useEffect } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function Todo() {
  const valueGetter = `
    some random text line 1
    some random text line 2
    some random text line 3
    some random text line 4
  `;
  const [code, setCode] = useState(valueGetter);
  const [count, setCount] = useState(0);
  const totalCount = useRef(0);

  const style = {
    maxHeight: "575px",
    minHeight: "538px",
    resize: "none",
    padding: "9px",
    boxSizing: "border-box",
    fontSize: "15px"
  };

  useEffect(() => {
    console.log("counts.current", count, totalCount.current);
    const stringArr = valueGetter.split(/\n/g);
    totalCount.current = stringArr.length;
    if (count > 0 && count < totalCount.current) {
      const newString = stringArr.splice(0, count).join("\n");
      // need to do someother logic
      setCode(newString);
    }
  });

  return (
    <>
      <button onClick={() => setCount(count + 1)}>Show value</button>
      <textarea value={code} style={style} />
    </>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Todo />, rootElement);