React中传递useRef给子组件为何未报错且正常运行?
为什么把useRef作为props传给子组件没报错还能正常运行?
我是React新手,得知将useRef()作为props传递给子组件并非正确方式,但为何该写法没有报错且能正常运行?相关代码如下:
const App = () => { const todoRef = useRef(null); const [todos, setTodos] = useState([]); const onFormSubmit = (e) => { e.preventDefault(); const todo = todoRef.current.value; if (todo.trim().length > 0) { setTodos((prevTodo) => [ ...prevTodo, { title: todo, isCompleted: false }, ]); todoRef.current.value = null; } }; return ( <div> <h1>Todos</h1> <InputField onFormSubmit={onFormSubmit} todoRef={todoRef} /> <TodoList todos={todos} /> </div> ); };
const InputField = ({ onFormSubmit, todoRef }) => { return ( <form onSubmit={onFormSubmit}> <input type="text" name="task" placeholder="What task needs to be completed?" ref={todoRef} /> </form> ); };
原因解析
首先,React本身不会禁止你把ref作为props传递,它只是不符合React推荐的数据流规范。useRef创建的是一个普通的JavaScript对象,结构就是{ current: ... },本质上和传递普通对象props没区别,所以React不会抛出错误,子组件也能正常接收并绑定到input上。
那为什么这种写法不推荐?核心问题有几点:
- 破坏组件封装性:子组件InputField本该自己管理输入框的状态,现在父组件直接通过ref操控它的DOM元素,子组件的内部实现被父组件耦合,后续修改InputField结构(比如替换input组件)会导致父组件代码失效。
- 违背单向数据流:React推荐数据从父到子通过props传递,状态变化通过回调通知父组件。直接用ref操作DOM属于绕开数据流的写法,代码会更难追踪和维护。
- 易混淆ref的用途:ref的设计初衷是访问DOM或组件实例,不是用来传递状态,这种写法会让你错误理解ref的正确使用场景。
规范写法示例
让子组件自己管理输入状态,通过回调把值传给父组件:
const App = () => { const [todos, setTodos] = useState([]); const onFormSubmit = (todo) => { if (todo.trim().length > 0) { setTodos((prevTodo) => [ ...prevTodo, { title: todo, isCompleted: false }, ]); } }; return ( <div> <h1>Todos</h1> <InputField onFormSubmit={onFormSubmit} /> <TodoList todos={todos} /> </div> ); }; const InputField = ({ onFormSubmit }) => { const [inputValue, setInputValue] = useState(''); const handleSubmit = (e) => { e.preventDefault(); onFormSubmit(inputValue); setInputValue(''); }; return ( <form onSubmit={handleSubmit}> <input type="text" name="task" placeholder="What task needs to be completed?" value={inputValue} onChange={(e) => setInputValue(e.target.value)} /> </form> ); };
内容的提问来源于stack exchange,提问作者Killer Bee
相关产品推荐
相关产品推荐

