1. prosp的只读性
1.1 纯函数
个人理解:纯函数就是函数内部不去更改入参的函数,并且相同的输入,总是会得到相同的输出,并且在执行过程中没有任何副作用。
这里的副作用指的是函数在执行过程中产生了外部可观察变化。
常见的副作用 (1)发起HTTP请求 (2)操作DOM (3)修改外部数据 (4)console.log()打印数据 (5)调用Date.now()或者Math.random()
如下代码的两个函数中,sum函数就是纯函数,因为它不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果。相比之下,withdraw就不是纯函数,因为它更改了自己的入参。另外xAdd也不是一个纯函数,因为程序执行的过程中,变量a很可能会发生改变,那么改函数得到的输出就会改变。
function sum(a, b) {
return a+b;
}
function withdraw(account, amount) {
account.total -= amount;
}
let a = 1;
function xAdd(x) {
return x + a;
};
xAdd(1);
1.1.1 纯函数的好处
(1)更容易进行测试,结果只依赖输入,测试时可以确保输出稳定 (2)更容易维护和重构,我们可以写出质量更高的代码 (3)更容易调用,我们不用担心函数会有什么副作用 (4)结果可以缓存,因为相同的输入总是会得到相同的输出
数组的很多基本方法都是纯函数,如map、forEach等等
在React中也遵循着『所有react组件 都必须要像纯函数一样保护它们的props不被更改』
1.1.2 纯函数组件
function Header(props) {
return <h2>{props.text}</h2>
}
class Header extends React.Component {
render() {
return <h1>{this.props.text}</h1>
}
}
纯函数组件的优点
(1)无副作用,我们不用担心副作用带来的一些难以捕捉的问题 (2)语法更简洁,可读性好,代码量相对较小,易复用 (3)占用内存小,无生命周期和状态管理,提升了性能
纯函数组件也有自己的缺点,例如:没有生命周期。所幸现在我们也已经有了很好的解决方案——react-hooks。利用hooks函数,我们可以在函数组件中使用等价于生命周期,状态管理等方法。
2. 条件渲染
你可以使用变量来存储元素,它可以做到帮助你有条件的渲染组件的一部分,而其他的渲染部分并不会因此而改变。
const renderPartOne = useMemo(
()=>{
return something;
},[]
)
或者
const button = <LogoutButton onClick={this.handleLogoutClick} />;
3. 受控组件 & 非受控组件
React 中的组件分两种,分别是(1)将状态变化交由 React 处理的组件(2)通过ref引用获取的组件。前者是受控组件,后者则为非受控组件。非受控组件的状态在组件自身存储,需要的时候通过ref查询DOM并查找其值。
多数情况下,推荐使用受控组件实现表单。在受控组件中,表单数据由组件控制。在非受控组件中,表单组件由dom自身控制
在react中,所谓受控组件和非受控组件是针对表单而言的。受控的概念其实就是:对某个组件来说,它的值是否只能由用户设置,而不能通过代码控制。
- 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似.
- 对于受控组件,输入的值始终由React的state驱动。
3.1 受控组件
代码中有一个输入框,界面展示了输入框的内容。随着输入框内容的变化,上方文字相应变化。表单组件input的值通过onchange回调交给react处理;react获取到表单的值(e.target.value)之后,将其保存到了状态变量name中。界面展示内容通过读取组件状态name,因此name的变化触发
hello {name}
的重新渲染。
export default function App() {
const [name, setName] = useState('');
const handleNameChange = e => {
setName(e.target.value);
}
return (
<div className="App">
<div>hello {name}</div>
姓名:<Input onChange={handleNameChange} />
</div>
);
}
3.2 非受控组件
非受控组件将数据存储在dom中,而不是组件内,这比较类似于传统的HTML表单元素。
- 非受控组件的值不收组件自身的state和props控制
- 非受控组件使用ref从dom中获取元素数据
页面中包含一个输入框和一个按钮,通过ref获取input元素的值;input值由用户改变,点击提交按钮,在handleSubmit中通过ref获取DOM 元素,进而读取输入框的值。输入框的变化并未交由组件控制,而是通过ref获取,也就是直接在dom中读取。
export default function App() {
const eleRef = useRef(null);
const [submitContent, setSubmitContent] = useState("");
const handleSubmit = () => {
const content = eleRef.current?.value;
setSubmitContent(content);
};
return (
<div className="App">
<input ref={eleRef} />
<Button type="primary" onClick={handleSubmit}>
提交
</Button>
<div>{submitContent ?? ""}</div>
</div>
);
}
3.3 总结
React中的组件分为受控组件和非受控组件。
- 受控组件的两个要点:
- 组件的value属性与React中的状态绑定
- 组件内声明了onChange事件处理value的变化
-
非受控组件更像是传统的HTML表单元素,数据存储在DOM中,而不是组件内部,获取数据的方式是通过ref引用 -
一些建议:
- 尽可能使用受控组件
- 受控组件是将状态交由React处理,可以是任何元素,不局限于表单元素
- 对于有大量表单元素的页面,使用受控组件会使程序变得繁琐难控,此时使用非受控组件更为明智
- 在受控组件中,数据流是单向的(state是变化来源),因此在改变state时都应该使用setState,而不要强制赋值
- Refs不能用于函数式组件,因为函数式组件没有实例
- 在函数式组件内部,是可以使用Refs的
5. 参考博客
纯函数是什么?怎么合理运用纯函数? 聊一聊React中的受控组件和非受控组件
|