React.FunctionComponent
React
提供了一个组件类型React.FunctionComponent
,可简写React.FC
,
- 能够接管一个泛型
p
,默认是{}
children
,返回一个React.ReactNode
,这个children
是任何component
都领有的- 动态属性
defaultProps
,组件的默认属性,内部能够不传这个属性。
interface IHelloProps {message?: string;}
const Hello: React.FunctionComponent<IHelloProps> = (props) => {return <h2>{props.message}</h2>;
};
Hello.defaultProps = {message: "Hello world",};
React Hook
- 齐全可选
- 百分百向后兼容
- 没有打算从
React
移除class
Hook
是一个非凡的函数,它能够让你勾入 React
个性,例如 useState
就容许在 React
函数组件增加state Hook
。
在编写函数组件时,意识到要向外面增加一些 State
时,以前的做法是必须转换成 Class
类型的组件,当初能够在现有的函数组件中应用Hook
useState
离开应用
import React, {useState} from "react";
const LikeButton: React.FC = () => {const [like, setLike] = useState(0);
const [on, setOn] = useState(true);
return (
<>
<button
onClick={() => {setLike(like + 1);
}}
>
{like}????
</button>
<button
onClick={() => {setOn(!on);
}}
>
{on ? "ON" : "OFF"}
</button>
</>
);
};
export default LikeButton;
合在一起应用
import React, {useState} from "react";
const LikeButton: React.FC = () => {const [obj, setObj] = useState({like: 1, on: true});
return (
<>
<button
onClick={() => {setObj({ like: obj.like + 1, on: obj.on});
}}
>
{obj.like}????
</button>
<button
onClick={() => {setObj({ like: obj.like, on: !obj.on});
}}
>
{obj.on ? "ON" : "OFF"}
</button>
</>
);
};
export default LikeButton;
删除数据
react
中有一个概念 immutable
,意思是不容许 state
有任何的扭转。
一旦批改 state
,前面做 react 性能做优化的时候会有问题。
const {list} = [...this.state.list];
list.splice(1, 1);
this.setState({list});
// 不举荐
this.state.list.splice(1, 1);
this.setState({list: this.state.list});
属性名
label
的 for
属性,在 jsx
中会和 for
循环抵触,react
用 htmlFor
来代替 label
标签的 for
<label htmlFor='insertArea'> 姓名 </label>
<input type='text' id='insertArea'/>
父组件和子组件通信
子组件操作父组件的数据:
- 父组件向子组件传递一个办法
- 子组件调用这个办法,间接的操作父组件的数据
class TodoList extends Component {deleteItem = (number) => {alert(number);
};
render() {return <TodoItem deleteItem={this.deleteItem} />;
}
}
class TodoItem extends Component {constructor(props) {super(props);
}
render() {return <div onClick={this.props.deleteItem(1)}> 按钮 </div>;
}
}
setState 接管函数
onClick(e) {
const value = e.target.value
this.setState(() => ({value}))
}
onClick() {
// prevState 是批改前的数据状态
this.setState((prevState) => ({list: [...prevState.list]
}))
}
PropTypes
限度父组件向子组件传值的类型
import PropTypes from "prop-types";
TodoItem.propTypes = {
test: PropTypes.string.isRequired,
content: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
deleteItem: PropTypes.func,
index: PropTypes.number,
};
defaultProps
属性默认值
TodoItem.defaultProps = {test: "hello world",};
虚构 DOM
当父组件的 render
函数被运行时,它的子组件的 render
也会被从新执行
- state 数数据
- JSX 模版
-
数据 + 模版 生成虚构 DOM(虚构 DOM 就是一个 js 对象,用它来形容正式的 DOM),(损耗了性能)。
["div", { id: "name"}, ["span", {}, "hello world"]];
-
用虚构 DOM 的构造生成实在的 DOM,来显示
<div id="abc"><span>abc</span></div>
- state 发生变化(setState 时,数据会发生变化)
-
数据 + 模版 生成新的虚构 DOM(极大晋升了性能),diff 算法,react 中的 diff 是同层比拟,如果第一层节点就产生了变动,上面就不在比拟了,间接全副替换
["div", { id: "name"}, ["span", {}, "bye bye"]];
- 比拟原始虚构 DOM 和新的虚构 DOM 的区别,找到区别的是 span 中的内容(极大晋升了性能)
- 间接操作 DOM,扭转 span 中的内容
Ref
react 倡议用数据驱动,尽量不要去操作 DOM
<input onChange={this.onChange} ref={(input) => (this.input = input)} />;
onChange = (e) => {
const value = this.input.value;
// 等价于
const value = e.target.value;
};
申明周期函数
- componentWillMount:组件在行将被挂载到页面时执行(第一次挂载的时候被执行)
- render
- componentDidMount:组件在被挂载到页面后执行(第一次挂载的时候被执行),ajax 申请最好发在这里
- shouldComponentUpdate:组件被更新之前执行(须要在函数外部返回 true,返回 false 不会执行)
- componentWillUpdate:组件被更新之前执行,但在 shouldComponentUpdate 之后(shouldComponentUpdate 返回 true 才会被执行)
- componentDidUpdate:组件更新完之后执行
-
componentWillReceiveProps:没有 props 参数,不会被执行
- 一个组件要从父组件接管参数
- 只有父组件的 render 函数被从新执行了,子组件的 componentWillReceiveProps 就会被执行(如果子组件第一次呈现在页面中,不会执行)
- componentWillUnmount:组件被移除前执行
shouldComponentUpdate
/**
* nextProps 一个组件更新时 props 会变动成什么样
* nextState 一个组件更新时 state 会变动成什么样
*/
shouldComponentUpdate(nextProps, nextState) {if(nextProps.content !== this.props.content) {return true} else {return false}
}
动画
装置 react-transition-group
import {CSSTransition} from "react-transtion-group";
<CSSTransition
in={this.stata.show} // 通知 CSSTransition 组件什么时候有动画
timeout={1000} // 动画时长 1s
className="fade"
unmountOnExit // 元素隐没后会被移除
appear={true} // 页面一刷新,也会有动画成果
>
<div>hello</div>
</CSSTransition>;
- fade-enter(动画进入前一瞬间)
- fade-enter-active(动画进入前第二霎时,始终到动画实现)
- fade-enter-done(进入动画实现时)
- fade-exit(动画隐没前一瞬间)
- fade-exit-active(动画隐没前第二霎时,始终到动画隐没实现)
- fade-exit-done(隐没动画实现时)
- fade-appear(动画进入前一瞬间)
- fade-appear-active(动画进入前第二霎时,始终到动画实现)