这是我在看了imooc中的React简书开发实战课程之后记下的笔记,在这做下备份,以便日后复习。
安装一下脚手架:
npx create-react-app my-app
cd my-app
npm start
一、dangerouslySetInnerHTML属性
当React元素包含html标签时,如果不设置dangerouslySetInnerHTML属性,就会把html当做字符串处理:
render() {
const value = '<h1>Hello World</h1>';
return (
<div>{value}</div>
);
}
浏览器中会输出:<h1>Hello World</h1>
如果想让html标签起作用,就要用到dangerouslySetInnerHTML属性:
render() {
const value = '<h1>Hello World</h1>';
return (
<div dangerouslySetInnerHTML={{__html: value}}></div>
);
}
浏览器中输出:
Hello World
启用dangerouslySetInnerHTML属性,可能会受到XSS攻击
二、JSX中需要注意的地方
- 注释的写法:
{/* 这里是注释 */}
或者是
{
//这里是注释
} - 需要注意的两个属性名:
html中label标签的for
属性,在JSX中要替换为htmlFor
html中class
属性,在JSX中要替换为className
三、this.setState
作用:修改this.state
一般用法:
this.setState({
value: myValue
});
这种用法有一个缺陷,就是使用this.setState
修改this.state
之后,页面并不会立即重新渲染,而是等组件的render
方法重新执行的时候才会去重新渲染页面。
这样,多次调用this.setState
产生的效果会合并。
关于
this.setState
推荐一篇好文章:setState:这个API设计到底怎么样
如果想要this.setState
的效果立即生效,就要使用它的函数式用法
:
this.setState(() => {
return {
value: myValue
}
});
可以简写成:
this.setState(() => ({
value: myValue
}));
this.setState
可以有一个prevState
参数:
this.setState((prevState) => ({ //prevState 等价于 this.state
//...
}));
this.setState
还可以有一个回调函数:
this.setState((prevState) => ({
//...
}), () => {
console.log('这是回调函数');
});
四、PropTypes
PropTypes
有两种用法:一是检测组件间传递的属性的类型,二是为组件间传递的属性设置默认值
使用首先需要添加一句话:
import PropTypes from 'PropTypes';
用法一:检测组件间传递的属性的类型
PropTypes.类型名
,用于限制子组件从父组件接收的参数类型
App.propTypes = { //App是一个组件名
//下面的oneOfType方法表示content的类型可以是string和number
content: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
deleteItem: PropTypes.func,
index: PropTypes.number.isRequired //isRequired 表示这个参数不能为空
}
内置的PropTypes
有:
PropTypes.array
PropTypes.bool
PropTypes.func
PropTypes.number
PropTypes.object
PropTypes.string
用法二:为组件间传递的属性设置默认值
当该组件没有接受到指定的参数时,就用默认值为这个参数赋值
App.defaultProps = { //App是个组件名
content: 'hello world'
}
五、ref属性
//this.state = { value: '' };
//tar和this.input中的input都可以是任意字符
<input ref={(tar) => {this.input = tar}} onChange={this.handleInputChange}></input>
handleInputChange() {
this.setState(() => ({
value: this.input.value
}));
}
上面的tar
就指向了ref
所在的DOM元素,将其赋值给this.input
,这样this.input
就等价于e.target
上面的this.input
一旦被定义之后,在整个render方法中都是可以获取到的,作用并不局限于代替e.target
这个属性不推荐使用,因为直接操作DOM不符合React的面向数据的思想
六、生命周期函数
Mounting时期:
componentWillMount //组件被挂载到页面之前执行(只会执行一次)
componentDidMount //组件被挂载到页面之后执行(只会执行一次)
Updation时期:
//当子组件将要从父组件接收参数时执行
//如果这个子组件第一次存在于父组件中,不会执行
//当这个子组件仍存在于父组件中,才会被执行
componentWillReceiveProps
//componentWillReceiveProps之后,componentWillUpdate之前执行
//用于判断页面是否需要被更新
//需要有返回值(Boolean类型): true 页面需要更新,false 页面不需要更新
shouldComponentUpdate
componentWillUpdate //组件将要被更新之前执行
componentDidUpdate //组件更新完成之后被执行
Unmount时期:
componentWillUnmount //当组件将要从页面去除的时候执行
声明周期函数的一些实际应用:
1.shouldComponentUpdate
//this.state = { content: '' };
//由于父组件render重新执行时,子组件的render也会被强制执行,
//此时子组件的数据并不一定改变,所以子组件并不一定需要重新执行render
//可以利用shoudlComponentUpdate函数,判断子组件的数据是否也发生了改变
//这样可以避免子组件做不必要的渲染,提高性能
shouldComponentUpdate(nextProps, nextState) { //两个参数分别表示:传进来的props和state
if (nextProps.content !== this.props.content) {
return true;
} else {
return false;
}
}
2.componentDidMount
//当使用ajax获取数据的时候,如果只用ajax获取一次数据
//那么将ajax代码放在componentDidMount中比较合适
//eg: 利用axios扩展发送ajax请求:
//先安装axios扩展: npm install axios
//重启localhost:3000
import axios from 'axios';
componentDidMount() { //将只获取一次数据的ajax代码放在这个函数里
axios.get('/api/todolist')
.then(() => {alert('succ')})
.catch(() => {alert('error')})
}
然后用charles
工具模拟出接口数据测试上面的ajax
请求是否有效。
七、charles本地模拟数据接口报404:
我用charles在本地模拟接口数据时一直会报404,后来发现用node运行react占用了3000端口,所以charles无法在3000端口模拟数据,不知道我看的那个课程视频上为什么可以。百度,谷歌翻烂也没找到答案。还好后来发现了一个在线mock接口数据的网站,终于又可以模拟数据愉快的玩耍啦!
传送门:Mock your HTTP responses to test your REST API
如有错误或不足,欢迎评论指正~
待续…