我正在玩钩子,我正在尝试执行以下操作:
import React, { useState, useRef } from 'react';const EditableField = () =>{const [isEditing, setEditing] = useState(false);const inputRef = useRef();const toggleEditing = () =>{setEditing(!isEditing);如果(正在编辑){inputRef.current.focus();}};返回 (<>{isExpanded &&<输入引用={输入引用}/>}<button onClick={toggleEditing}>编辑</button></>);};这会失败,因为 current 为空,因为组件还没有重新渲染,输入字段还没有渲染(因此还不能聚焦).
这样做的正确方法是什么?我可以使用 在 React Hooks 常见问题解答中提出了 usePrevious hook,但这似乎是一个痛苦的解决方法.
有什么不同的方法吗?
解决方案您可以使用 useEffect 钩子在每次渲染后在 isEditing 改变时运行一个函数.在此函数中,您可以检查 isEditing 是否为 true 并聚焦输入.
示例
const { useState, useRef, useEffect } = React;const EditableField = () =>{const [isEditing, setEditing] = useState(false);const toggleEditing = () =>{setEditing(!isEditing);};const inputRef = useRef(null);useEffect(() => {如果(正在编辑){inputRef.current.focus();}}, [isEditing]);返回 (<div>{isEditing &&<输入引用={输入引用}/>}<button onClick={toggleEditing}>编辑</button>);};ReactDOM.render(, document.getElementById("root"));
<script src="unpkg/react@16.7.0-alpha.2/umd/react.production.min.js"></script><script src="unpkg/react-dom@16.7.0-alpha.2/umd/react-dom.production.min.js"></script><div id="root"></div>I'm playing with hooks, and I'm trying to do the following:
import React, { useState, useRef } from 'react'; const EditableField = () => { const [isEditing, setEditing] = useState(false); const inputRef = useRef(); const toggleEditing = () => { setEditing(!isEditing); if (isEditing) { inputRef.current.focus(); } }; return ( <> {isExpanded && <input ref={inputRef} />} <button onClick={toggleEditing}>Edit</button> </> ); };This is going to fail, because current is null, since the component haven't re-rendered yet, and the input field is not yet rendered (and therefore can't be focused yet).
What is the right way to do this? I can use the usePrevious hook proposed in the React Hooks FAQ, but it seems like a painful workaround.
Is there a different way?
解决方案You can use the useEffect hook to run a function after every render when isEditing changed. In this function you can check if isEditing is true and focus the input.
Example
const { useState, useRef, useEffect } = React; const EditableField = () => { const [isEditing, setEditing] = useState(false); const toggleEditing = () => { setEditing(!isEditing); }; const inputRef = useRef(null); useEffect(() => { if (isEditing) { inputRef.current.focus(); } }, [isEditing]); return ( <div> {isEditing && <input ref={inputRef} />} <button onClick={toggleEditing}>Edit</button> </div> ); }; ReactDOM.render(<EditableField />, document.getElementById("root"));<script src="unpkg/react@16.7.0-alpha.2/umd/react.production.min.js"></script> <script src="unpkg/react-dom@16.7.0-alpha.2/umd/react-dom.production.min.js"></script> <div id="root"></div>
更多推荐
如何使用 React Hooks 专注于下一次渲染
发布评论