);
}
}
- 以上几种方法,React 推荐使用 click3 的实现方法,重写如下:
class Button extends React.Component {
constructor(){
super();
this.name = “Bob”;
this.click = this.click.bind(this);
}
click(){
console.log(hello ${this.name}
);
}
render(){
return (
Click me
);
}
}
- 传递参数给事件的时候,第一个参数为 id, 第二个参数为 event。实际调用可以去以下两种方式:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row
<button onClick={this.deleteRow.bind(this, id, e)}>Delete Row
- 以上两种方法等效,后一个方法的参数 e 可以省略。
条件渲染
根据不同的条件(通常指state)渲染不同的内容, 比如下面段代码可以根据 isLoggenIn
渲染不同的问候语:
function UserGreeting(props) {
return
Welcome back!
;}
function GuestGreeting(props) {
return
Please sign up.
;}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) { // 根据 isLoggenIn 渲染不同的问候语
return ;
}
return ;
}
ReactDOM.render(
// 你可以尝试设置 isLoggedIn={true}:
,
document.getElementById(‘root’)
);
下面用 class 实现一个复杂一点的,带有登录/注销按钮的:
function LoginButton(props) {
return (
登录
);
}
function LogoutButton(props) {
return (
注销
);
}
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false
};
// 修正 this 绑定
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
}
handleLoginClick() {
this.setState({isLoggedIn: true});
}
handleLogoutClick() {
this.setState({isLoggedIn: false});
}
render() {
const { isLoggedIn } = this.state;
let button = null;
if (isLoggedIn) {
button = ;
} else {
button = ;
}
return (
{/* Greeting 取自上一个示例 (注意这里的注释写法)*/}
{button}
);
}
}
ReactDOM.render(
,
document.getElementById(‘root’)
);
当然,对于这样一个简单的示例,使用 if 可能你会觉的太复杂了,我们也可以使用 &&
?:
这些运算符来代替 if 语句,就像写 javascript 代码一样。我们极力的化简一下上面的代码:
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false
};
}
render() {
const { isLoggedIn } = this.state;
const button = isLoggedIn ?
-
<button onClick={() => { this.setState({isLoggedIn: false}); }}>注销
- <button onClick={() => { this.setState({isLoggedIn: true}); }}>登录;
return (
{
isLoggedIn ? ‘Welcome back!’ : ‘Please sign up.’
}
{button}
);
}
}
ReactDOM.render(
,
document.getElementById(‘root’)
);
当然,如果你需要在某个条件下不进行渲染,那么直接输出 null 即可,比如下面这个组件,在 props.warn
为 false
时不渲染任何内容:
function WarningBanner(props) {
if (!props.warn) {
return null;
}
return (
Warning!
);
}
需要注意的是,即便你输出了 null, react 也会再渲染一次。同理,componentWillUpdate
和 componentDidUpdate
也会被调用。
列表
–
在 React 中我们可以使用 map() 方法渲染列表,比如如下这个例子,将一组数据映射(map)为一组 dom:
const data = [1, 2, 3, 4, 5];
const listItems = data.map((item) =>
- {item}
);
ReactDOM.render(
- {listItems}
document.getElementById(‘root’)
);
我们注意到这里我们给 li (即列表的每个元素)标签加了一个 key 属性,这个 key 用来帮助 React 判断哪个元素发生了改变、添加或移除。关于这个 key 我们需要明白以下几点:
-
最好保证 key 是一个字符串,并且在该列表中唯一,如果你的数据中实在没有唯一的 key 可以选择,那么就使用数组的索引(index)吧(不推荐这样)
-
值得注意的是,如果你不给每个元素指定一个 key, react 会默认使用索引(index)作为 key
-
key 的值只是给 React 起到类似暗示的作用,不会真正的传递给 dom, 所以如果你需要使用 key 的值,应使用一个其它变量传递该值。
当然,上面代码我们也可以写成 inline 的形式:
const data = [1, 2, 3, 4, 5];
ReactDOM.render(
{
data.map((item) =>
- {item}
);
}
,document.getElementById(‘root’)
);
表单
–
表单的处理会和原生的 html 有一些区别,因为 React 可以很好的帮助你使用 js 控制你的表单,这里我们需要引入一个新的概念:受控组件。
受控组件说白了就是其值受 react 控制的组件。其中,表单的元素通常都会具有其自己的 state,该值会随着用户的输入改变。比如下面这个例子,会在用户提交时输出用户的名字:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ‘’};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ’ + this.state.value);
event.preventDefault();
}
render() {
return (
Name:
);
}
}
不难发现,这里使用了,onchange 事件不断的将用户的输入绑定到 this.state.value 上,然后通过和用户输入同步的重绘实现数据的显示。这样可以很好的控制用户输入,比如同步的将用户输入转化为大写:
handleChange(event) {
this.setState({value: event.target.value.toUpperCase()});
}
理解了上面的内容我们可以知道,单纯给一个 input 赋值一个值用户是不能修改的,比如下面这行代码:
ReactDOM.render(, mountNode);
但如果你不小心他的值设为 null 或 undefined(等同于没有 value 属性),这个 input 就可以被更改了:
ReactDOM.render(, mountNode);
setTimeout(function() {
ReactDOM.render(, mountNode);
}, 1000);
在 React 中 textarea 也是通过 value 属性实现其内容变化的,而非其子节点:
class EssayForm extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ‘Please write an essay about your favorite DOM element.’
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('An essay was submitted: ’ + this.state.value);
event.preventDefault();
}
render() {
return (
Essay:
); } } 在 React 中,对于 select 也会显得很方便,你不需要在 option 中通过 selected 改变其值了,而是在 select 标签上通过 value 属性实现: class FlavorForm extends React.Component { constructor(props) { super(props); this.state = {value: 'coconut'}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert('Your favorite flavor is: ' + this.state.value); event.preventDefault(); } render() { return ( ); } } 上面代码默认选中 Coconut。 这里值得注意的是,对于多选框,你可以传入一个数组作为值: