这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战。
以结果为导向,写给刚学完前端三剑客和想要了解 React 框架的小伙伴,使得他们能快速上手(省略了历史以及一些不必要的介绍)。
children prop
You can think of a component with a
children
prop as having a “hole” that can be “filled in” by its parent components with arbitrary JSX.
我们将通过 React 的 children prop 像使用 HTML 开合标签一样使用 React 元素,把之前使用的文本 ”Search: “ 从上层传下来,不再使用 label prop:
const App = () => {
...
return (
<>
<InputWithLabel
id="search"
value={searchTerm}
onInputChange={handleSearch}
>
<strong>Search:</strong>
</InputWithLabel>
<hr />
<List list={searchedStories} />
</>
);
};
const InputWithLabel = ({
id,
value,
type = "text",
onInputChange,
children,
}) => (
<>
<label htmlFor={id}>{children}</label>
<input id={id} type={type} value={value} onChange={onInputChange} />
</>
);
复制代码
我们可以把字符串, HTML 元素 <strong>
,以及【组件】等任意 JSX 元素当作 React children 传递,有了这个特性,我们可以就像使用 HTML 元素一样交织使用 React 组件。
指令式 React
从 JSX 到 hook,一直都是我们告诉 React 去渲染什么,而不是怎么去渲染,所以 React 天生是声明式的。
但并不是所有时候都能使用声明的方式,有些情况我们不免要通过指令式的方式去访问渲染好的 JSX 元素,比如我们需要调用 DOM API 的 focus()
方法给搜索框添加一个自动聚焦的功能。
- 命令式写法,设定属性值:
const App = () => {
...
return (
<>
<InputWithLabel
id="search"
value={searchTerm}
onInputChange={handleSearch}
isFocused
>
<strong>Search:</strong>
</InputWithLabel>
<hr />
<List list={searchedStories} />
</>
);
};
const InputWithLabel = ({
id,
value,
type = "text",
onInputChange,
children,
isFocused,
}) => (
<>
<label htmlFor={id}>{children}</label>
<input
id={id}
type={type}
value={value}
onChange={onInputChange}
autoFocus={isFocused}
/>
</>
);
复制代码
- 指令式写法,通过程序调用 DOM API:
const InputWithLabel = ({
id,
value,
type = "text",
onInputChange,
children,
isFocused,
}) => {
const inputRef = React.useRef(); // 1
React.useEffect(() => { // 3
if (isFocused && inputRef.current) {
inputRef.current.focus(); // 4
}
}, [isFocused]);
return (
<>
<label htmlFor={id}>{children}</label>
{/* 2 */}
<input
ref={inputRef}
id={id}
type={type}
value={value}
onChange={onInputChange}
/>
</>
);
};
复制代码
- 首先,使用 useRef hook 创建一个 ref ,也就是一个引用对象。它在组件的整个生命周期中保持不变,向外暴露一个可变的 current 属性,并把初始化被传入的参数作为 current 属性值。
- 把 ref 对象通过 JSX 的 ref 标签传递给输入框之后,这个 DOM 节点就会被赋给 current 属性,也就是说
inputRef.current
现在已经指向了挂载在 DOM 上的输入框节点。 - 调用 useEffect hook,当组件渲染或是依赖数组改变时,使焦点落在输入框上。
- 最后,当设置了
isFocused
并且 current 属性存在时,通过 current 属性访问到输入框实现自动聚焦。
Essentially,
useRef
is like a “box” that can hold a mutable value in its.current
property.
也就是说我们通过 useRef hook 拿到了 DOM 节点并且调用了 DOM API,把原来的声明式转换为了指令式,更多 useRef 的用法可以查看官方文档。
专栏
因为参加打卡活动是每日更新,所以可能比较短小,可以关注一下 React 入门专栏。
在更新完后会整合为一整篇,感谢关注和点赞!