- 元素是构成 React 应用的最小单位,JSX 就是用来声明 React 当中的元素。
- 样式
- 数组
- 创建组件
- 向组件传递参数,可以使用 this.props 对象,实例如下:
- 使用React.Component 的 ES6 类,该类封装了要展示的元素,需要注意的是在 render() 方法中,需要使用 this.props 替换 props:来获取值
- ()=>this.tick() 是 ES6 中声明函数的一种方式,叫做箭头函数表达式,引入箭头函数有两个方面的作用:更简短的函数并且不绑定 this。
- React Props
- 默认 Props
- React 事件处理
- 阻止组件渲染
- key的正确使用方式:当你在 map() 方法的内部调用元素时,你最好随时记得为每一个元素加上一个独一无二的 key。
- key 会作为给 React 的提示,但不会传递给你的组件。如果您的组件中需要使用和 key 相同的值,请将其作为属性传递:
- setState更新是同步还是异步(8课时)
- 强制更新:forceUpdate()
- 生命周期
- 条件渲染-{xxx ? :}; 列表渲染-数组遍历{this.xxx.map(()=>{return() })}
- 表单
- Select 下拉菜单
- 状态提升(父子通信)
- 组件组合和继承—类似vue插槽
- antd按需加载(用到哪个css,引入哪个css)
- fecth基于promise: get请求 post请求 VS
- react 项目中使用了typescript,是否还需要使用prop-types来进行格式验证。????
To learn React, check out the React documentation.
元素是构成 React 应用的最小单位,JSX 就是用来声明 React 当中的元素。
与浏览器的DOM元素不同,React当中的元素实际是普通的对象
React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。
要将 React 元素渲染到根 DOM 节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:
ps:由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。
在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。以下实例中如果变量 i 等于 1 浏览器将输出 true, 如果修改 i 的值,则会输出 false.
ReactDOM.render(<div><h1>{i == 1 ? 'True!' : 'False'}</h1></div>,document.getElementById('example'));
样式
React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式:
var myStyle = {
fontSize: 100,
color: '#FF0000'
};
ReactDOM.render(
<h1 style = {myStyle}>菜鸟教程</h1>,
document.getElementById('example')
);
数组
JSX 允许在模板中插入数组,数组会自动遍历展开所有成员:
var arr = [
<h1>菜鸟教程</h1>,
<h2>学的不仅是技术,更是梦想!</h2>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);
创建组件
1.我们可以使用函数定义了一个组件:
function HelloMessage(props) {
return <h1>Hello World!</h1>;
}
----
2.也可以使用 ES6 class 来定义一个组件:
class Welcome extends React.Component {
render() {
return <h1>Hello World!</h1>;
}
}
注意,原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。
向组件传递参数,可以使用 this.props 对象,实例如下:
使用React.Component 的 ES6 类,该类封装了要展示的元素,需要注意的是在 render() 方法中,需要使用 this.props 替换 props:来获取值
function Clock(props) {
return (
<div>
<h1>Hello, world!</h1>
<h2>现在是 {props.date.toLocaleTimeString()}.</h2> //props.value
</div>
);
}
function tick() {
ReactDOM.render(
<Clock date={new Date()} />,
document.getElementById('example')
);
}
setInterval(tick, 1000);
-----
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>现在是 {this.props.date.toLocaleTimeString()}.</h2> //this.props.value
</div>
);
}
}
function tick() {
ReactDOM.render(
<Clock date={new Date()} />,
document.getElementById('example')
);
}
setInterval(tick, 1000);
()=>this.tick() 是 ES6 中声明函数的一种方式,叫做箭头函数表达式,引入箭头函数有两个方面的作用:更简短的函数并且不绑定 this。
var f = ([参数]) => 表达式(单一)
// 等价于以下写法
var f = function([参数]){
return 表达式;
}
React Props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
State 和 Props
以下实例演示了如何在应用中组合使用 state 和 props 。我们可以在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据。
class WebSite extends React.Component {
constructor() {
super();
this.state = {
name: "xxx",
site: "https://www.xxx.com"
}
}
render() {
return (
<div>
<Name name={this.state.name} />
<Link site={this.state.site} />
</div>
);
}
}
class Name extends React.Component {
render() {
return (
<h1>{this.props.name}</h1>
);
}
}
class Link extends React.Component {
render() {
return (
<a href={this.props.site}>
{this.props.site}
</a>
);
}
}
ReactDOM.render(
<WebSite />,
document.getElementById('example')
);
默认 Props
你可以通过组件类的 defaultProps 属性为 props 设置默认值,实例如下:
class HelloMessage extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1> //编译后:Hello, Runoob
);
}
}
HelloMessage.defaultProps = {
name: 'Runoob'
};
const element = <HelloMessage/>;
ReactDOM.render(
element,
document.getElementById('example')
)
React 事件处理
在 React 中另一个不同是你不能使用返回 false 的方式阻止默认行为, 你必须明确的使用 preventDefault。
一般:
<a href="#" onclick="console.log('点击链接'); return false">
点我
</a>
react中:
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('链接被点击');
}
return (
<a href="#" onClick={handleClick}>
点我
</a>
);
}
阻止组件渲染
在极少数情况下,你可能希望隐藏组件,即使它被其他组件渲染。让 render 方法返回 null 而不是它的渲染结果即可实现。
在下面的例子中, 根据属性 warn 的值条件渲染。如果 warn 的值是 false,则组件不会渲染:
function WarningBanner(props) {
if (!props.warn) {
return null;
}
return (
<div className="warning">
警告!
</div>
);
}
class Page extends React.Component {
constructor(props) {
super(props);
this.state = {showWarning: true}
this.handleToggleClick = this.handleToggleClick.bind(this);
}
handleToggleClick() {
this.setState(prevState => ({
showWarning: !prevState.showWarning
}));
}
render() {
return (
<div>
<WarningBanner warn={this.state.showWarning} />
<button onClick={this.handleToggleClick}>
{this.state.showWarning ? '隐藏' : '显示'}
</button>
</div>
);
}
}
ReactDOM.render(
<Page />,
document.getElementById('example')
);
key的正确使用方式:当你在 map() 方法的内部调用元素时,你最好随时记得为每一个元素加上一个独一无二的 key。
function ListItem(props) {
// 对啦!这里不需要指定key:
return <li>{props.value}</li>;
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// 对啦!key应该在数组的上下文中被指定
<ListItem key={number.toString()}
value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('example')
);
key 会作为给 React 的提示,但不会传递给你的组件。如果您的组件中需要使用和 key 相同的值,请将其作为属性传递:
const content = posts.map((post) =>
<Post
key={post.id}
id={post.id}
title={post.title} />
);
setState更新是同步还是异步(8课时)
1.setState会引起视图的重绘
2.在可控的情况下是可以异步的。非可控的情况下是同步(通过async,await,promise)
3.不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换。
4.setState()并不会立即改变this.state,而是创建一个即将处理的state。setState()并不一定是同步的,为了提升性能React会批量执行state和DOM渲染。
5.setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染逻辑。
6.构造函数是唯一能够初始化 this.state 的地方。(不要直接更新状态,应当使用 setState()==== this.setState({comment: ‘Hello’});)
7.状态更新可能是异步的: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
}));
class Counter extends React.Component{
constructor(props) {
super(props);
this.state = {clickCount: 0};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(function(state) {
return {clickCount: state.clickCount + 1};
});
}
render () {
return (<h2 onClick={this.handleClick}>点我!点击次数为: {this.state.clickCount}</h2>);
}
}
ReactDOM.render(
<Counter />,
document.getElementById('example')
);
强制更新:forceUpdate()
callback,可选参数,回调函数。该函数会在组件render()方法调用后调用。
forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。
forceUpdate()方法适用于this.props和this.state之外的组件重绘(如:修改了this.state后),通过该方法通知React需要调用render()
一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。
生命周期
render() 初始以及更新,都会触发一遍,所以setState发生重绘。。
初始状态:count:0
Component WILL MOUNT!
Component DID MOUNT!
数据更新:count:1,触发3个生命周期
Component WILL RECEIVE PROPS!
Inline Babel script:37 Component WILL UPDATE!
Inline Babel script:40 Component DID UPDATE!
条件渲染-{xxx ? :}; 列表渲染-数组遍历{this.xxx.map(()=>{return() })}
表单
1.受控组件—内部state管理—表单适用
2.非受控组件—dom管理,Ref管理
使用场景:
管理焦点,文本选择,或媒体播放
触发强制动画
集成第三方dom库
使用方法:
ref=“id”或者
input框比较多时,每个input绑定一个事件时,推荐使用非受控组件
首先: this.id=React.createRef()
<input ref={this.id} value=“”></input>
获取当前dom时的值:this.id.current.value
Select 下拉菜单
在 React 中,不使用 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 (
<form onSubmit={this.handleSubmit}>
<label>
选择您最喜欢的网站
<select value={this.state.value} onChange={this.handleChange}>
<option value="gg">Google</option>
<option value="rn">Runoob</option>
<option value="tb">Taobao</option>
<option value="fb">Facebook</option>
</select>
</label>
<input type="submit" value="提交" />
</form>
);
}
}
ReactDOM.render(
<FlavorForm />,
document.getElementById('example')
);
状态提升(父子通信)
组件之间的数据交互
组件组合和继承—类似vue插槽
this.props.children
antd按需加载(用到哪个css,引入哪个css)
1手动引入
2webpack配置: 使用babel-plugin-import
