React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合。
并没有采用将标记与逻辑分离到不同文件这种人为的分离方式,而是通过将二者共同存放在称之为“组件”的松散耦合单元之中,来实现关注点分离。
react原则:
1.大括号内放置任何有效的 JavaScript 表达式
2.所有 React 组件都必须像纯函数一样保护它们的 props 不被更改
3.State 与 props 类似,但是 state 是私有的,并且完全受控于当前组件
4.多个组件需要反映相同的变化数据,这时我们建议将共享状态提升到最近的共同父组件中去
5.推荐使用组合而非继承来实现组件间的代码重用
等效代码:
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
// 注意:这是简化过的结构
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
组件 & Props
接受任意的入参(即 “props”),返回用于描述页面展示内容的 React 元素
函数组件 本质是javascript函数
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
class组件
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
渲染组件
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const root = ReactDOM.createRoot(document.getElementById('root'));
const element = <Welcome name="Sara" />;
root.render(element);
当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。
State & 生命周期
this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
要解决这个问题,可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
受控组件和非受控组件
状态属性
表单元素有这么几种属于状态的属性:
- value,对应 和 所有
- checked,对应类型为 checkbox 和 radio 的 所有
- selected,对应 所有
对于设置了上面提到的对应“状态属性“值的表单元素就是受控表单组件
render: function() {
return <input type="text" value="hello"/>;
}
和受控组件相对,如果表单元素没有设置自己的“状态属性”,或者属性值设置为 null,这时候就是非受控组件。
为什么要有受控组件?
引入受控组件不是说它有什么好处,而是因为 React 的 UI 渲染机制,对于表单元素不得不引入这一特殊的处理方式。
在浏览器 DOM 里面是有区分 attribute 和 property 的。attribute 是在 HTML 里指定的属性,而每个 HTML 元素在 JS 对应是一个 DOM 节点对象,这个对象拥有的属性就是 property(可以在 console 里展开一个 DOM 节点对象看一下,HTML attributes 只是对应其中的一部分属性),attribute 对应的 property 会从 attribute 拿到初始值,有些会有相同的名称,但是有些名称会不一样,比如 attribute class 对应的 property 就是 className。(详细解释:.prop,.prop() vs .attr())
回到 React 里的 输入框,当用户输入内容的时候,输入框的 value property 会改变,但是 value attribute 依然会是 HTML 上指定的值(attribute 要用 setAttribute 去更改)。
高级指引
context
Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。