高阶组件即接受组件返回组件,形式如下:
const HoC=Component=>EnhanceComponent
案例: 对获取数据封装
对数据获取渲染,我们会这么做…
export default class UserList extends Component {
state = {
list: []
}
componentDidMount() {
fetch('')
.then(response => response.json())
.then(list => this.setState({ list }))
}
render() {
return (
<>
<ul>
{
this.state.list.map(user => (
<li key={user.id}>{user['name']}</li>
))
}
</ul>
</>
)
}
}
封装获取数据后,可以让多处代码获取同一个api数据。我们可以这么做…
const widthData: IWidthData = url => Component => {
return class extends React.Component {
constructor(props: any) {
super(props);
this.state = { list: [{name:'cc',id:'1'}] }
}
componentDidMount() {
fetch(url)
.then(response => response.json())
.then(list => this.setState({ list }))
}
render() {
return <Component {...this.props} {...this.state} />
}
}
}
type IList = Readonly<{
list: any[]
}>;
const List = ({ list }: IList) => (
<ul>
{
list.map(user => (
<li key={user.id}>{user['name']}</li>
))
}
</ul>
);
export default widthData('url')(List)
//这里也可以使用props动态修改url,修改方案如下
componentDidMount(){
const _url=typeof url ==='function'?url(this.props):url;
// ...
}
export default widthData(props=>`url/${props.username}`)(List)
const style={
color:'blue'
};
const Button=()=><button style={style}>click me</button>
通过行内样式我们可以动态去修改样式,但是也存在缺陷:
import radium from 'radium'
const styles={
backgroundColor:'#ff0000',
width:320,
padding:20,
borderRadius:5,
border:'none',
outline:'none',
':hover':{
color:'#fff',
backgroundColor:'blue'
},
'@media (max-width:480)':{
width:160
}
};
const Button=()=><button style={styles}>click me </button>
export default radium(Button);
import styles from './btn.module.css'
const Button=()=><button className={styles.btn} >click me </button>
//btn.module.css
.btn{
background-color:'#ff0000';
width:320;
padding:20;
border-radius:5;
border:'none';
outline:'none';
}
import cssModules from 'react-css-modules'
const Button = () => <button styleName="button">Click me!</button>;
export default cssModules(Button, styles)
import styled from 'styled-components'
const Button=styled.button`
background:#ff0000;
width:320px;
padding:20px;
border-radius:5px;
border: none;
outline: none;
`;
export default Button;
两者区别:命令式编程描述代码如何工作,而声明式编程则表明想要实现什么目的。
例如下面将大写字符串的数组变小写字符串数组,两者编程的区别:
命令时编程这么做:
const toLowerCase=input=>{
const output=[];
for(let i=0;i<input.length;i++){
output.push(input[i].toLowerCase())
}
return output;
}
声明式编程这么做:
const toLowerCase=input=>input.map(v=>v.toLowerCase());
它是一种声明式范式,能够避免代码副作用,同时推崇数据不可变。
它是函数编程的常用技巧,过程是将多参数函数转换成单参数函数,这些单参数函数返回值也是函数。
react-refetch
react-addons-css-transition-group
react-motion
radium
react-css-modules
style-components