日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

React在組件中如何監聽redux中state狀態的改變_React

作者:承蒙時光不棄1769203735 ? 更新時間: 2022-10-02 編程語言

在組件中監聽redux中state狀態的改變

解決方式

1、在組件中引入store

2、在constructor構造器方法中,重寫store.subscribe方法(該方法即是監聽state狀態改變的放過)

組件完整代碼如下:?

import React, { Component } from 'react'
import CSSModules from 'react-css-modules'?
import { connect } from 'react-redux'
import store from '../../redux/store'?
import styles from './BgMusic.css'
?
@CSSModules(styles)
class BgMusic extends Component {
? // 構造器
? constructor(props) {
? ? super(props)
? ? console.log('執行了constructor')
? ? // 監聽state狀態改變
? ? store.subscribe(() => {
? ? ? console.log('state狀態改變了,新狀態如下')
? ? ? console.log(store.getState())
? ? ? const state = store.getState()
? ? ? if (state.music.play) {
? ? ? ? // 播放背景音樂
? ? ? ? this.audio1.play()
? ? ? }
? ? ? else {
? ? ? ? // 暫停背景音樂
? ? ? ? this.audio1.pause()
? ? ? }
? ? })
? }
? render() {
? ? return (
? ? ? <div className={styles.container}>
? ? ? ? <audio ref={audio1 => { this.audio1 = audio1 }} className={styles.hidden} autoPlay="autoplay" controls="controls" loop="loop" preload="auto" src="./music/music.mp3">
? ? ? ? ? ? 你的瀏覽器版本太低,不支持audio標簽
? ? ? ? </audio>
? ? ? </div>
? ? )
? }
}
export default connect(
? // 這里的state,就是公共容器中的state,而不是當前組件的state。在這里定義了之后,在當前組件中,就可以通過this.props.music拿到該對象
? state => ({ music: state.music }),
)(BgMusic)

React和redux的狀態處理

我們知道react中state是組件更新的唯一指標,并且只能通過組件的this.setState方法觸發組件的重新渲染。這種形式導致了一個組件A想要觸發另一個組件B更新,就必須觸發組件B內部的this.setState。一般是通過一開始就在B中設置委托到組件A中。

例如:?

class B extends React.Component{
    state={key:"value"}
    handle(){
        this.setState({key:"newvalue"})
    }
    render(){
        return <div> 
                <A onOk=>{this.handle.bind(this)}/>
                <span>{this.state.key}</span>
            </div>
    }
}
class A extends React.Component{
    render(){return <button onClick={this.props.onOk}>click</button>}
}

這樣也就隱形的要求B組件必須是A組件的父組件,換句話說:如果一個組件想要觸發另一個組件的更新,需要觸發者是被觸發者的子組件。 父組件可以將更新的函數預先定好,作為屬性傳入子組件中,這樣子組件中調用這個屬性函數就觸發了父組件的更新,本質是父組件將自己的一個函數委托給子組件處理。

當組件變得又多又復雜的時候,可能需要跨越好多層父子關系來傳遞這個閉包,這使得狀態的管理非常復雜。

這里寫圖片描述

例如這種情況下,C想要觸發A.setState,那就需要A先封好閉包作為屬性傳給B,B再傳給C,C在合適的時機調用。調用完了,A的setState會引起所有的子組件重新render。

如果C想要觸發D的更新,則也需要A作為中介,將D中要更新的部分拿出來,作為props由A來傳入,這樣還是按照之前的做法,C可以引起A的render,進而導致了所有組件render,也就包括了D。不過其實我們只想要D更新,其他組件并不需要更新。而且我們看到state的存儲很亂,有時候我們將state存到本組件中,由自己掌握更新的時機,有時候需要交給父組件來掌握,此時子組件是無狀態的,所有數據由父組件通過props傳入。

這種方式無論從閉包傳遞還是過多的組件render上都是不好的,我們思考能不能通過更高效的方式完成這件事。首先是閉包傳遞,其實本質上是A把更新這件事放到一個函數中,然后把該函數作為屬性傳遞給了子組件。我們可以這樣來做,在A中設置一個事件監聽器當事件觸發的時候就更新狀態,而在C中設置一個事件激發當合適的時機(如點擊按鈕)觸發這個事件,這樣就完成了直接觸發另一個組件的更新。這樣每個組件都有自己的state,并且都監聽一個自己特定的事件,如果事件觸發,就相應的調用setState完成自己的更新。

Redux就是這種思路,核心概念是store,所有組件ABCDE的state都存到了store.state中,這個變量只能通過觸發action才能改變,并且專門定義了這種根據action更新store.state值的函數叫reducer。當然了改變了這個變量的值對我們整個react應用沒有任何影響,還需要把這個值和每個組件內的state關聯起來。每個組件中都有一個store.subcribe(func),即每個組件都可以監聽這個store.state的變化,如果變化就觸發這個函數,然后可以看變量中是不是和自己相關的例如可以在store中這樣存儲{a:xxx,b:xx,c:xx,d:xx}這樣A只需要檢查store.getState().a是不是有變。

如下:

這里寫圖片描述

上圖中,其實ABCD的回調函數都會觸發,只不過觸發后有個判斷,只有D的發生了變化,所以只有D進行后續setState和render操作。

Redux的思想是這樣的,首先state全都交到store中來保存,每個組件訂閱store的變化,一但發生變化,就把自己的state同步。store的變化由action這種方式唯一觸發,管理起來也方便。不過Subscribe寫起來太麻煩了,所以ReactRedux模塊提供了Provider 和connect,可以很方便的完成自動Subscribe和自動封裝無狀態組件為有邏輯的組件,這種情況下我們只要寫無狀態組件,省了很多工作量。

原文鏈接:https://blog.csdn.net/qq_36742720/article/details/86226428

欄目分類
最近更新