如何使用 React 在单独的 div 中动态显示文本区域的值?

How do I dynamically display the value of a textarea in a separate div using React?

我正在使用 React(初学者)开发降价预览器,我正在尝试在页面上单独的 div 中显示文本区域的当前值。我不确定如何最好地使用 React 处理 textarea 值。

我的组件层次结构如下:

目前,我的 App 组件中有一个函数可以处理对 textarea 的更改 - 它作为 props 传递给 Editor 组件,并进一步传递到 Textarea 组件,在 onChange 事件之后调用它:

function App() {
  const handleTextChange = () => {
    const textarea = document.getElementById("textarea");
    let text;
    if (textarea === null) {
      text = "";
    } else {
      text = textarea.value;
    }
    console.log(text);
    return text;
  };

  return (
    <div className="App">
      <Header />
      <div className="App-body">
        <Editor handleTextChange={handleTextChange} />
        <Preview />
      </div>
    </div>
  );
}

export default App;

此功能正在运行 - 我可以在输入时看到控制台中的文本区域值正在更新。

问题如下:

React(和 Stack Overflow)新手 - 任何建议(或相关问题的链接)表示赞赏

How should I pass this value to the desination div? Does this need to involve State, so that the destination div re-renders every time the textarea value changes?

这是通常的方式,是的。

Was declaring the handleTextChange function within my App component the right approach to begin with? Is there are better way to achieve this result?

handleTextChange 很好,但问题是您如何访问文本区域。一般来说,您不应该为此访问 DOM。相反,使 textarea 成为 controlled component(因此它的值保持在状态中)并在呈现 textarea 时使用该状态预览 div.

这是一个非常基本的例子:

const {useState} = React;

// The `Editor` component receives the value and the change function as
// props. I've called the change function `handleTextChange` so you can
// see how it relates to your code, but I might well have called it
// `setValue` otherWise.
const Editor = React.memo(({value, handleTextChange}) => {
    // Our change handler just extracts the value from the textarea
    // and passes it on. No need to memoize it here, probably,
    // but if you wanted to you could use `useCallback` with the
    // dependency array [handleTextChange].
    const onChange = e => handleTextChange(e.target.value)
    return (
        <textarea
            value={value}
            onChange={e => handleTextChange(e.target.value)}
        />
    );
});

// The Preview component shows the text
const Preview = ({text}) => {
    return <div>{text}</div>;
};

// Just a stand-in
const Header = () => <div>(Header)</div>;

function App() {
    // The state for the text and its setter
    const [text, setText] = useState("");
  
    // Notice how we can pass the state setter directly to `Editor`
    // as `handleTextChange` below.
    return (
        <div className="App">
            <Header />
            <div className="App-body">
                <Editor handleTextChange={setText} />
                <Preview text={text} />
            </div>
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

首先,您有两种类型的组件:ES6 class 组件(可以通过 this.state 使用状态)和您的情况下的功能组件。功能组件不能使用 React 状态,但 React 中引入了一个新功能,称为反应钩子(useState hook)。在你的情况下,你需要在你的应用程序组件中使用一个状态变量,然后通过道具将这个状态传递给你的组件。您需要设置组件的状态,并在 handleText 更改函数中将其作为 prop 传递给预览组件。