React 元件通訊
目錄
元件通訊
元件是獨立且封閉的單元 , 預設情況下 , 只能使用元件自己的資料 . 在元件化過程中 , 我們將一個完整的功能拆分成多個元件 , 以更好地完成整個應用的功能 . 而在這個過程中 , 多個元件之間不可避免的要共享某些資料 . 為了實現這些功能 , 就需要打破元件的獨立封閉性 , 讓其與外界溝通 . 這個過程就是元件通訊
元件的Props
- 元件是封閉的 , 要接受外部資料應該通過 props 來實現
- props的作用: 接收傳遞給元件的資料
- 傳遞資料: 給元件標籤新增屬性
- 接收資料: 函式元件通過引數props接收資料 , 類元件通過 this.props 接收資料
<Hello name="jack" age={ 19 } />
// 函式元件
function Hello(props) {
console.log(props);
return (
<div>接收到資料:{props.name}</div>
)
}
ReactDOM.render(<Hello name='zs' age={19} />, document.getElementById('root'))
// 類元件
class Hello extends React.Component {
render() {
return (
<div>接收到的資料:{this.props.age}</div>
)
}
}
ReactDOM.render(<Hello name='zs' age={19} />, document.getElementById('root'))
特點
- 可以給元件傳遞任意型別的資料
- props 是只讀的物件 , 只能讀取屬性的值 , 無法修改物件
-
注意: 使用類元件時候 , 如果寫了建構函式 , 應該將props 傳遞給 super() , 否則 , 無法在建構函式中獲取到props
class Hello extends React.Component {
constructor(props) {
super(props)
console.log(this.props);
}
render() {
return (
<div>接收到的資料:{this.props.age}</div>
)
}
}
ReactDOM.render(<Hello name='zs' age={19} />, document.getElementById('root'))
元件通訊的三種方式
元件之間的通訊分為3種:
- 父元件 => 子元件
- 子元件 => 父元件
- 兄弟元件
父元件傳遞資料給子元件
- 父元件提供要傳遞的state資料
- 給子元件標籤新增屬性 , 值為 state 中的資料
- 子元件中通過 props 接受父元件中傳遞的資料
// 父元件 => 子元件
// 父元件
class Parent extends React.Component {
state = { lastName: '吳' }
render() {
return (
<div>
傳遞資料給子元件:<Child name={this.state.lastName} />
</div>
)
}
}
//子元件
function Child(props) {
return <div>子元件收到資料:{props.name}</div>
}
子元件傳遞資料給父元件
思路: 利用回撥函式 , 父元件提供回撥 , 子元件呼叫 , 將要傳遞的資料作為回撥函式的引數
- 父元件提供一個回撥函式( 用於接收資料 )
- 將該函式作為屬性的值 , 傳遞給子元件
- 子元件通過 props 呼叫回撥函式
- 將子元件的資料作為引數傳遞給回撥函式
// 父元件
class Parent extends React.Component {
getChildMsg = (data) => {
console.log('接收到子元件資料', data);
}
render() {
return (
<div className="parent">
父元件:<Child getMsg={this.getChildMsg} />
</div>
)
}
}
//子元件
class Child extends React.Component {
state = { ChildMsg: "React" }
handleClick = () => {
this.props.getMsg(this.state.ChildMsg)
}
render() {
return (
<button onClick={this.handleClick}>給父元件傳值</button>
)
}
}
ReactDOM.render(<Parent name='zs' age={19} />, document.getElementById('root'))
注意: 回撥函式中 this 指向問題
兄弟元件
- 將 共享狀態 提升到最近的公共父元件中 , 由公共父元件管理這個狀態
- 思想: 狀態提升
- 公共父元件職責
- 提升共享狀態
- 提供操作共享狀態的方法
- 要通訊的子元件只需通過 props 接收狀態或操作狀態的方法
// 父元件
class Counter extends React.Component {
// 提供共享狀態
state = {
count: 0
}
// 提供修改狀態的方法
onIncrement = (data) => {
this.setState({
count: this.state.count + data
})
}
render() {
return (
<div>
<Child1 count={this.state.count} />
<Child2 getData={this.onIncrement} />
</div>
)
}
}
// 子元件
const Child1 = (props) => {
return <h1>計數器:{props.count}</h1>
}
// 子元件
const Child2 = (props) => {
return <button onClick={() => props.getData(1)}>+1</button>
}
ReactDOM.render(<Counter />, document.getElementById('root'))
Context
- 處理方式: 使用 props 一層層元件往下傳遞 ( 繁瑣 )
- 更好的姿勢: 使用 Context
- 作用: 跨元件傳遞資料 ( 比如: 主題 , 語言等 )
使用步驟:
1. 呼叫 React.createContext() 建立 Provider (提供資料) 和 Consumer (消費資料) 兩個元件
const { Provider , Consumer } = React.createContext()
2. 使用 Provider 元件作為父節點
<Provider>
<div className="App">
<Child1 />
</div>
</Provider>
3. 設定 value 屬性 , 表示要傳遞的資料
<Provieder value="pauline_">
4. 呼叫 Consumer 元件接收資料
<Consumer>
{ data => <span> data 參數列示接受資料 -- { data } </span>
<Consumer>
const { Provider, Consumer } = React.createContext()
class App extends React.Component {
render() {
return (
<Provider value="pauline_">
<div className="App" >
<Node />
</div>
</Provider>
)
}
}
const Node = props => {
return (
<div className="node">
<SubNode />
</div>
)
}
const SubNode = props => {
return (
<div className="subnode">
<Child />
</div>
)
}
const Child = props => {
return <div className="child">
// data表示接受資料 -- pauline_
<Consumer>{data => <span>data表示接受資料 -- {data}</span>}</Consumer>
</div>
}
ReactDOM.render(<App />, document.getElementById('root'))
props 深入
children 屬性
- children 屬性 : 表示元件標籤的子節點. 當元件標籤有子節點時 , props就會有該屬性
- children 屬性與普通 props 一樣 , 值可以是任意值( 文字 , React元素 , 元件 , 甚至是函式 )
function Hello(props) {
console.log(props);
return (
<div>
元件的子節點: {props.children}
</div>
)
}
ReactDOM.render(<Hello>我是子節點</Hello>, document.getElementById('root'))
props 效驗
- 對於元件來說 , props是外來的 , 無法保證元件使用者傳入什麼格式的資料
- 如果傳入的資料格式不對 , 可能會導致元件內部報錯
- 關鍵問題: 元件的使用者不知道明確的錯誤原因
- props 效驗: 允許在建立元件的時候 , 就指定props的型別 . 格式等
- 作用: 捕獲使用元件時因為 props 導致的錯誤 , 給出明確的錯誤提示 , 增加元件的健壯性
App.propTypes = {
colors : PropTypes.array
使用步驟
1.安裝包
2. 匯入 prop-types 包
3. 使用 元件名.propTypes = {} 來給元件的props新增效驗規則
function App(props) {
return (
<h1>Hi , {props.colors}</h1>
)
}
App.propTypes = {
// 約定colors 屬性為Array型別
// 如果型別不對 , 則報出明顯錯誤 , 便於分析錯誤原因
colors: PropTypes.array
}
ReactDOM.render(<App />, document.getElementById('root'))
約束規則
- 常見型別: array , bool , func , number , object , string
- React 元素型別 : element
- 必填項 : isRequired
// 常見型別
element: PropTypes.func,
//必選
element: PropTypes.func.isRequired,
// 特定結構的物件
element: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
})
props的預設值
- 場景: 分頁元件 => 每頁顯示條數
function App(props) {
console.log(props);
return (
<div>
此處展示props的預設值:{props.pageSize}
</div>
)
}
//設定預設值
App.defaultProps = {
pageSize: 10
}
// 不傳入pageSize屬性
ReactDOM.render(<App colors={[1, 2, 3]} />, document.getElementById('root'))
相關文章
- React元件通訊React元件
- 【React】元件通訊 - 跨層通訊React元件
- React 《元件間通訊》React元件
- react元件通訊通識篇React元件
- React - 元件之間的通訊React元件
- 我學react之父子元件通訊React元件
- React中元件間通訊的方式React元件
- React中元件之間通訊的方式React元件
- 5.React中元件通訊問題React元件
- React中元件通訊的幾種方式React元件
- “React元件間通訊”學習筆記React元件筆記
- 會vue,學習react元件父子通訊VueReact元件
- React之元件(component)之間的通訊React元件
- React中元件間通訊的幾種方式React元件
- React.js 中的元件通訊問題ReactJS元件
- 一起學React--元件定義和元件通訊React元件
- react通訊React
- 關於React父子元件通訊知識總結React元件
- 【vue元件通訊①】父元件向子元件通訊propsVue元件
- React: 關於React通訊方式React
- 深入解析React資料傳遞之元件內部通訊React元件
- vue元件通訊Vue元件
- 元件(7) —— 通訊元件
- vue 元件通訊Vue元件
- Vue — 元件通訊Vue元件
- Vue元件通訊方式Vue元件
- vue 父子元件通訊Vue元件
- vue常用元件通訊Vue元件
- Vue 元件的通訊Vue元件
- react之組建通訊React
- Vue中父子元件通訊——元件todolistVue元件
- vue 2 0 元件:父子元件通訊Vue元件
- Vue 元件間的通訊Vue元件
- Vue 父子元件的通訊Vue元件
- 元件通訊 provide inject元件IDE
- Vue元件間的通訊Vue元件
- 父子元件之間通訊元件
- react父子、子父、兄弟通訊React