React 不答应组件访问其他组件的 DOM 节点。乃至自己的子组件也不行!这是故意的。Refs 是一种脱围机制,应该谨慎利用。手动操作 另一个 组件的 DOM 节点会使你的代码更加脆弱。
相反,想要 暴露其 DOM 节点的组件必须选择该行为。一个组件可以指定将它的 ref “转发”给一个子组件。
- import { forwardRef, useRef } from 'react';
- const MyInput = forwardRef((props, ref) => {
- return <input {...props} ref={ref} />;
- });
- export default function Form() {
- const inputRef = useRef(null);
- function handleClick() {
- inputRef.current.focus();
- }
- return (
- <>
- <MyInput ref={inputRef} />
- <button onClick={handleClick}>
- 聚焦输入框
- </button>
- </>
- );
- }
复制代码 flushSync 强制 React 同步更新
- import { useState, useRef } from 'react';
- import { flushSync } from 'react-dom';
- export default function TodoList() {
- const listRef = useRef(null);
- const [text, setText] = useState('');
- const [todos, setTodos] = useState(
- initialTodos
- );
- function handleAdd() {
- const newTodo = { id: nextId++, text: text };
- flushSync(() => {
- setText('');
- setTodos([ ...todos, newTodo]);
- });
- listRef.current.lastChild.scrollIntoView({
- behavior: 'smooth',
- block: 'nearest'
- });
- }
- return (
- <>
- <button onClick={handleAdd}>
- 添加
- </button>
- <input
- value={text}
- onChange={e => setText(e.target.value)}
- />
- <ul ref={listRef}>
- {todos.map(todo => (
- <li key={todo.id}>{todo.text}</li>
- ))}
- </ul>
- </>
- );
- }
- let nextId = 0;
- let initialTodos = [];
- for (let i = 0; i < 20; i++) {
- initialTodos.push({
- id: nextId++,
- text: '待办 #' + (i + 1)
- });
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |