第 22 天 !
当我们资料项下传递的时候,
会发现,
component
的阶层越深,
传递资讯会越困难,
因为代表的是,需要不断做向下传递的动作,
假如阶层数太多,会导致我们中间传递过程中段的话,
很容易造成错误,
打个比方:
假如最後参数要使用在 Child3 , 起点在 App
<App>
<Child1>
<Child2>
<Child3></Child3>
</Child2>
</Child1>
</App>
那我们就必须照这样的路径 App -> Child1 -> Child2 -> Child3
把资料送到 Child3
这样做会产生一些问题:
那在 React
里,有个可以打破这个规矩的存在,
就是 context
!!
context
分为 Provider(提供者)
& Consumer(消费者)
当使用 context
时,
会由 Provider 建立 value , 并广播给相同 context 的 Consumer ,
那中间不用经过 props 的传递 ,
关系就是 Provider
-> Consumer
我们要使用 React.createContext
来建立,
import React from 'react';
export const AppContext = React.createContext({
theme: {},
toggleTheme: () => {},
});
createContext
本身塞入欲要提供的参数格式,非此定义的,都无法做传送
那在我们要建立 Provider
的 component
下引入我们定义好的 context
,并把 Provider 放进去
like:
<AppContext.Provider value={this.state.contextParams}>
<SafeAreaView style={styles.root}>
<Header
searchList={this.searchList}
createToDoItem={this.createToDoItem}
handleCompleteAll={this.handleCompleteAll}
/>
<FlatList
data={list.filter((item) => item.text.includes(filterKey))}
renderItem={({ item, index, separators }) => {
const isEven = index % 2 === 0;
const isDone = item.status === 'done';
return (
<ToDoItem
isEven={isEven}
isDone={isDone}
text={item.text}
onPress={this.changeItemStatus(item.id)}
/>
);
}}
keyExtractor={(item) => item.id}
/>
</SafeAreaView>
</AppContext.Provider>
建立好的 context 会提供两个 component ,
Provider 放在资料源头, 会提供一个 props value,
在此置入我们要提供的参数物件,
那只要 value 有变动 , 相应的 Consumer 也会产生变动,
那变动的判定方式就是用 Shallow compare (===)
去判定,
所以不能用 inline 的方式植入 value ,
否则会产生无意义的渲染,徒增消耗,
所以会放入 state 去定义,
那为什麽要放入 state ,
因为只有这样才能去触发 re-render
, value
才能改变
this.state = {
filterKey: '',
inputValue: '',
list: [],
contextParams: {
theme: {
header: {
backgroundColor: '#cfcf00',
},
},
toggleTheme: this.toggleTheme,
},
};
假如希望 context 里的值,可以在 Consumer 上做改变,
那必须提供相应的改变 function,
toggleTheme = (backgroundColor) => {
this.setState((prevState) => ({
contextParams: {
theme: {
header: {
backgroundColor,
},
},
},
...prevState.contextParams,
}));
};
那在指定的 component
, 放入 Consumer
export class Header extends Component {
render() {
return (
<AppContext.Consumer>
{({ theme, toggleTheme }) => {
return (
<View style={[styles.root, theme.header]}>
<Text style={styles.title}>My To Do List</Text>
<View style={styles.buttonGroup}>
<FeatureButton
text={'Change Color'}
onPress={() => toggleTheme('#F0F')}
/>
</View>
</View>
);
}}
</AppContext.Consumer>
);
}
}
Consumer
的里面放入的是 component,
不是React element ,
它会把 context
用 props
方式传入,
我们得到 theme
& toggleTheme
,
用 theme.header
定义 Header component
背景颜色,
用 toggleTheme 改变
结果如下:
>>: Day22 - 针对 Metasploitable 3 进行渗透测试(3) - Msfvenom 与 multi/handler
这礼拜进度缓慢了下来,还在跟第六周的切版作业奋斗。到这边才慢慢找到自己切版比较顺的流程 RWD 一开...
本篇文章同步发表在 HKT 线上教室 部落格,线上影音教学课程已上架至 Udemy 和 Youtu...
参赛动机 笔者正在转职前端工程师的路上,过去一直知道有铁人赛,也有参加的念头,但由於本人的惰性及害怕...
当object中的function作为callback function传递给setTimeout时...
在本地化 (localize) 文字讯息时,我们可能会遇到需要特别处理 HTML tag的情况,什...