JSX标签
在JSX代码的外面套一个小括号
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
函数定义/类定义组件
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
上面两个组件在React中是相同的。
组件名称必须以大写字母开头。
例如,<div />
表示一个DOM标签,但 <Welcome />
表示一个组件,并且在使用该组件时你必须定义或引入它。
组件的 挂载
方法componentDidMount
:第一次加载到DOM中的时候生成定时器;
组件的 卸载
方法componentWillUnmount
:DOM被移除的时候关闭定时器;
正确地使用状态
- 不要直接更新状态
例如,此代码不会重新渲染组件:
// Wrong
this.state.comment = 'Hello';
应当使用 setState():
// Correct
this.setState({comment: 'Hello'});
构造函数是唯一能够初始化 this.state 的地方。
2.状态更新可能是异步的
React
可以将多个setState()
调用合并成一个调用来提高性能。
因为 this.props
和 this.state
可能是异步更新的,你不应该依靠它们的值来计算下一个状态。
例如,此代码可能无法更新计数器:
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
要修复它,请使用第二种形式的 setState() 来接受一个函数而不是一个对象。 该函数将接收先前的状态作为第一个参数,将此次更新被应用时的props
做为第二个参数:
// Correct
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
3.状态更新合并
4.数据自顶向下流动
事件处理
React 元素的事件处理和 DOM元素的很相似。但是有一点语法上的不同:
1.React事件绑定属性的命名采用驼峰式
写法,而不是小写。
2.如果采用 JSX 的语法你需要传入一个函数
作为事件处理函数,而不是一个字符串(DOM元素的写法)
***********:在 React 中另一个不同是你不能使用返回 false 的方式阻止默认行为。你必须明确的使用 preventDefault。例如,传统的 HTML 中阻止链接默认打开一个新页面,你可以这样写:
表单多个输入
当你有处理多个受控的input元素时,你可以通过给每个元素添加一个name属性,来让处理函数根据 event.target.name的值来选择做什么。
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
组合 vs 继承
1.包含关系
一些组件不能提前知道它们的子组件是什么。这对于 Sidebar 或 Dialog 这类通用容器尤其常见。
我们建议这些组件使用 children
属性将子元素直接传递到输出
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
这样做还允许其他组件通过嵌套 JSX 来传递子组件。
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
虽然不太常见,但有时你可能需要在组件中有多个入口,这种情况下你可以使用自己约定的属性而不是 children:
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}
function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}