小知识
事件处理
通过返回false
的方式阻止默认行为的问题
在React中另一个不同点是你不能通过返回false
的方式阻止默认行为. 你必须显式的使用preventDefault
. 例如,传统的HTML中阻止链接默认打开一个新页面, 可以这样写:
<a href="#" onclick="console.log('The link was clicked.'); return false">
Click me
</a>
在React中, 可能是这样的:
function ActionLink() {
function handleClick(e) {
// 这里的e是合成事件
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href='#' onClick={handleClick}>
Click me
</a>
)
}
JSX回调函数中的this问题
必须谨慎对待JSX回调函数中的this
, 在JavaScript中, class的方法是默认不会绑定this
.如果忘记绑定this.handleClick
并把它传入了onClick
, 当你调用这个函数的时候this
的值为undefined
.
这与JavaScript函数工作原理有关. 通常情况下, 如果没有在方法后面添加()
, 例如onClick={this.handleClick}
, 你应该为这个方法绑定this
.
class Test extends React.Component {
constructor(props) {
super(props);
// 为了在回调中使用`this`, 这个绑定是必不可少的
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// xxx代码
}
render() {
return (
<button onClick={this.handleClick}>
按钮
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
两种简化的方法
class Test extends React.Component {
// 注意: 这是*实验性*&的语法
// 此语法确保`handleClick` 内的`this`已被绑定
handleClick = () => {
console.log('this is:', this)
}
render() {
return (
<button onClick={this.handleClick}>
按钮
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
class Test extends React.Component {
handleClick() {
console.log('this is:', this)
}
render() {
return (
// 此语法确保`handleClick` 内的`this`已被绑定
<button onClick={() => this.handleClick()}>
按钮
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
向事件处理程序传递参数
以下两种方式都可以向事件处理函数传递参数:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
还能这样用的与运算符 &&
通过花括号包裹代码, 可以在JSX中嵌入任何表达式. 这也包括JavaScript中的逻辑与(&&)运算符. 它可以很方便地进行元素的条件渲染.
function Mailbox(props) {
const unreadMeassages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0} &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
</div>
)
}
const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDom.render(
<MailBox unreadMessages={messages} />,
document.getElementById('root')
)
true && expression = expression
false && expression = false
列表&Key
arrays.map((array) => xxx)
JSX允许在大括号里嵌入任何表达式
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map((number) => number * 2);
console.lop(doubled);
const numbers = [1, 2, 3, 4, 5]
const listItems= numbers.map((number) =>
<li>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
解决a key should be provided for list items
的警告
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// 每个列表元素分配一个key属性
<li key={number.toString()}>
{number}
</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
Key
key 帮助React识别哪些元素改变了, 比如被添加或删除. key最好是列表中独一无二的字符串.
当元素没有确定id的时候, 万不得已可以使用元素索引index作为key.
- 元素的key只有放
ES6计算属性名称的语法更新给定输入名称对应的state值:
this.setState({
// name动态数据
[name]: value
});
等于ES5:
var partialState = {};
partialState[name] = value;
this.setState(partialState)
表单
在受控组件上指定value的prop会阻止用户更改输入. 如果你指定了value
, 但输入仍可编辑, 则可能是意外的将value
设置为undefined
或null
.
ReactDOM.render(<input value='hi' />, mountNode);
// 输入最初被锁定, 但在短时间延迟后变为可编辑
setTimeOut(function() {
ReactDOM.render(<imput value={null} />, mountNode);
}, 10000);
参考
[React]React.事件处理
[React]React.条件渲染
[React]React.列表&Key
[React]React.表单