时刻注意⚠️:
state应该存在的组件层次;经常地,我们都知道应该由更高的层次去拥有state。
一、无障碍辅助功能;
Accessibility,简称:a11y;使得辅助技术正确解读网页的必要条件。
1、语义化的HTML
利用多种HTML元素来强化网站中的信息;
使用React Fragments;如果fragment标签中不需要添加任何prop且工具支持的话,可以使用<> 短语法;
function Glossary(props) {
return (
<dl>
{props.items.map(item => (
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment>
))}
</dl>
);
}
function ListItem({ item }) {
return (
<>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</>
);
}
2、控制焦点
键盘导航:
Ctrl + Tab:可以在不同的控件间移动键盘焦点;
Ctrl + 方向键:在列表视图中,在不改变选中项的情况下,将键盘焦点移动到另一个选项;
- 跳过内容机制:使用地标元素和角色,比如:
<main>
和<aside>
作为辅助来划分网页的区域,让用户快速导航至这些部分。
3、Refs的使用
引用(Refs)提供了一个获得DOM节点或者创建在render方法中的React元素的方法;
——使用Refs的情况:
- 管理焦点、文本选择、媒体回放
- 触发必要动画
- 整合第三方DOM库
——创建Refs:通过React.createRef()创建Refs并通过ref属性联系到React组件。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
——访问Refs:当一个ref通过render放入一个元素中,一个对节点的引用可以通过ref的current属性得到;
const node = this.myRef.current;
ref的值根据节点类型的不同而不同:
- 当ref属性用于HTML元素,在构造器中通过React.createRef()函数创建的ref接收底层DOM元素作为它的current属性;
- 当ref属性用于传统的类组件,ref对象接收挂载好的组件实例作为它的current;
- 不能将ref属性用于函数式组件,因为它们没有实例。
1)DOM元素
通过current去获得DOM节点;
如果该DOM节点是input元素,那么可以使用node.focus()
让该元素获得焦点(focus使用了原生的DOM API)
React在组件挂载时将DOM元素分配给current属性;组件卸载时,将current属性重置为null;
2)类组件
如果想要包装CustomTextInput
这个类组件,模仿挂载后被点击;可以通过ref
得到CustomTextInput
组件,之后调用这个组件中的focusTextInput
方法。
class AutoFocusTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
componentDidMount() {
this.textInput.current.focusTextInput();
}
render() {
return (
<CustomTextInput ref={this.textInput} />
);
}
}
3)函数式组件 像引用DOM元素一样使用ref属性
function CustomTextInput(props) {
// textInput 必须被声明在这里——ref才能适用于它
let textInput = React.createRef();
function handleClick() {
textInput.current.focus();
}
return (
<div>
<input
type="text"
ref={textInput} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}
——回调Refs
放入一个函数,而不是由createRef()创建的ref属性;这个是函数接收React组件实例或者HTML DOM元素作为参数;
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.setTextInputRef = element => {
this.textInput = element;
};
this.focusTextInput = () => {
// 通过原生DOM API聚焦文本
if (this.textInput) this.textInput.focus();
};
}
componentDidMount() {
// 在挂载时自动聚焦
this.focusTextInput();
}
render() {
// 使用'ref'回调去在一个实例域中储存文本输入DOM元素的引用(比如, this.textInput).
return (
<div>
<input
type="text"
ref={this.setTextInputRef}
/>
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
——父组件把焦点设置在其子组件的一个元素上;通过在子组件上设置一个特殊的prop来对父组件暴露DOM refs,从而把父组件的ref传向子节点的DOM节点。
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.inputElement = React.createRef();
}
render() {
return (
<CustomTextInput inputRef={this.inputElement} />
);
}
}
// 现在你就可以在需要时设置焦点了
this.inputElement.current.focus();