前言:
此时朋友们对“js只读修改”大体比较重视,同学们都需要知道一些“js只读修改”的相关内容。那么小编在网上汇集了一些对于“js只读修改””的相关文章,希望兄弟们能喜欢,朋友们一起来学习一下吧!React 官方文档说法:
React is pretty flexible but it has a single strict rule: all React components must act like pure functions with respect to their props.
props 是组件的只读属性,组件内部不能直接修改 props,要想修改 props,只能在该组件的上层组件中修改
在 React 中,props 是上层组件传递进来的值,这个值是父类的值,同 Vue 一样,props 的传值是单项数据流,也就是不会让影响父类的值,如果需要改值,可以先让 props 赋值给一个变量,在修改这个变量。
其实就是保证 React 单向数据流的设计模式,使状态可预测。
如果允许子组件修改,那么一个父组件将状态传递给好几个子组件,这几个子组件随意修改,就完全不可预测,不知道在什么地方修改了状态。
一、解决了什么问题?
props是组件(包括函数组件和class组件)间的内置属性,用其可以传递数据给子节点。
二、怎么使用?1、只读
props在传递数据的过程中,是只读得不能修改。
class App extends React.Component { // 第一步:给节点设置属性 `theme` render() { return <Toolbar theme="dark" />; }}function Toolbar(props) { // 第二步:子节点可以访问父节点的props属性,但只能读取不能修改 return ( <div> <ThemedButton theme={props.theme} /> </div> );}class ThemedButton extends React.Component { // 第三步:孙子节点依然可访问props属性,同样只能读不能修改 render() { return <Button theme={this.props.theme} />; }}2、{...props}
展开props属性的一种简洁写法,属于 js展开语法 。
var props = { x: 1, y: 1, z:1 };<Component {...props} />// 上面等价于下面的写法<Component x=1 y=1 z=1 />3、props.children
只见组件的子元素,下面 {props.children} 就是指 : "Hello world!"
<Welcome>Hello world!</Welcome>function Welcome(props) { return <p>{props.children}</p>;}
对于 class 组件,请使用 this.props.children 来获取:
class Welcome extends React.Component { render() { return <p>{this.props.children}</p>; }}
在React组件开发时,Props是不可以修改的。但Why?如何尽可能确保在实际开发中被修改呢?继续喵
React中关于Props解释
Whether you declare a component as a function or a class, it must never modify its own props.
React is pretty flexible but it has a single strict rule:
All React components must act like pure functions with respect to their props.
结论React类库并没有强制约束不可以修改props,但是规则是不可以修改,是的,这是个Rule函数组件或者类组件都不要修改Props,避免产生副作用举个例子
// App renders a user.name and a profileconst App = (props) => React.createElement("div", null, [ props.user.name, React.createElement(Profile, props) ]);// Profile changes the user.name and renders it// Now App has the wrong DOM.const Profile = ({ user }) => { user.name = "Voldemort"; // Uh oh! return React.createElement("div", null, user.name);};// Render the App and give it propsReactDOM.render( React.createElement(App, { user: { name: "Hermione" } }), document.getElementById("app"));
如上,虽然在子组件中我们将user.name进行了修改,但是父组件打印的仍然是Hermione,原因?因为props是个对象,本身并没有修改,React组件更新时的新旧比较时浅对比。
React组件TypeScript定义
class Component<P, S> { constructor(props: Readonly<P>); ...
如上可以看出Props是只读参数,这样确保了一定的安全,假如我们直接赋值,会TSC报错
这样就没事了?No,假如参数是个对象类型呢?
如上,不会报错,但是个BUG。根本问题在于当前的Type定义无法确保属性的嵌套属性是只读的。关于这点,其实社区已经有讨论和解决方案,但是当前还没有将新的定义合并进去。
讨论戳这里
当前我们如何确保绝对的不可修改呢?可以将新的定义自己手动放入项目中即可。
Redux Saga中的Select
在组件中,我们使用Redux的值,是以Props形式进行使用,所以仍然应该只读使用。另一种使用场景是在effects中使用const state = yield select();,那么这里的state也应该只读吗?
YES,select实际上就是调用的store.get(key),某个state。注意实际上是个对象,那么假如我们在effects中修改了这个对象,实际上就是修改了单一状态树。因此当我们select拿到状态,注意保持只读性
Angular,Vue中的Props?
Angular,Vue中对于父组件传递过来的参数,并没有明确说明不可以修改,但注意本身在使用方式上都是组件,所以建议也不要修改。
写在最后
理解这些基本的设计规则及理念,有益于使用这些技术,同时对于设计模式也会有帮助。
标签: #js只读修改