簡體   English   中英

React:如何從Redux / Flux操作訪問組件引用?

[英]React: How to access component refs from Redux/Flux actions?

在實現像Redux或MobX這樣的狀態容器時,通常會將狀態和事件移動到不再能讀取引用的單獨類或對象。

例如,在正常組件中:

import Alert from Alert.js;

class Dummy extends React.Component {
  constructor(props) {
    super(props);

    this.state = { clicked: false }
  }

  handleClick() {
    fetch('api').then(function(){
      this.setState({ clicked: true });
      this._alert.show('Cool response!');
    });
  }

  render() {
    return (
      <div>
        <Alert ref={a => this._alert = a} />
        <Button onClick={this.handleClick}/>
      </div>
    )
  }
}

如果單擊該按鈕,則在完成服務器請求后,將更新狀態並觸發警報。 在某些模態和警報庫中使用這樣的引用是很常見的。

現在,在Redux(或任何Flux實現)中,fetch()將存在於一個動作中,該動作位於一個單獨的文件中,該文件無法訪問this._alert

在不重寫外部“警報”庫的情況下維護功能的最佳方法是什么?

作為一個說明,我來自你的帖子: https//dannyherran.com/2017/03/react-redux-mobx-takeaways/

這從一開始就是錯誤的。 不應在組件之間共享參考,因為它們將它們耦合在一起。 組件應設計成彼此完全分離,並根據給定的狀態做出反應。

問題是,ref告訴你組件本身的狀態,你不知道它是否已經安裝,你不知道它是否存在,所以你正在玩一些不穩定的東西。

因此,讓我們解耦所有內容並正確利用react / redux的強大功能, 所有代碼都應該以這種方式組織:

1.減速劑:

Reducer將保持警報的顯示狀態。 整個應用程序中的任何組件現在都可以訪問它,與refs 無關 ,因此組件實際存在與否無關緊要。

const DummyPageReducer = function(state, action) 
{
    if (state === undefined) 
    {
        state = 
        {
            alertShow: false
        };
    }

    switch(action.type) 
    {
        case 'ALERT_DISPLAY':
            return Object.assign({}, state, { alertShow: action.display });
    }
    return state;
}

2.動作和異步動作:

調整警報顯示設置的操作,以及執行獲取並生成正確結果的異步操作。

export const ALERT_DISPLAY = 'ALERT_DISPLAY '
export function alertDisplay(display) 
{
    return {
        type: ALERT_DISPLAY,
        display
    }
}

export function showAlert() 
{   
    return function (dispatch) 
    {  
        fetch('api').then(function()
        {
            dispatch(alertDisplay(true))
        });

    }

}

3.連接組件:

連通組件。 無需共享refs,將使用ref,但組件將對其給定的props做出反應並相應地設置Alert。

import Alert from Alert.js;

class Dummy extends React.Component 
{
    constructor(props) 
    {
        super(props);

        this.setAlert = this.setAlert.bind(this);
    }

    setAlert()
    {
        if(this.props.alertShow)
            this._alert.show('Cool response!');
        else
            this._alert.hide();

    }

    componenDidMount()
    {
        setAlert();
    }

    componentDidUpdate(prevProps, prevState)
    {
        if(prevProps.alertShow !== this.props.alertShow)
            setAlert();
    }

    render() 
    {
        return 
        (
            <div>
                <Alert ref={a => this._alert = a} />
                <Button onClick={this.props.showAlert}/>
            </div>
        )
    }
}
Dummy = connect(

    state => 
    ({
        alertShow: state.Dummy.alertShow
    }),

    dispatch =>
    ({
        showAlert: () => dispatch(showAlert(true))
    })

)(Dummy);

首先,您是否嘗試在handleClick中使用箭頭功能?

handleClick() {
    fetch('api').then(() => {
        this.setState({ clicked: true });
        this._alert.show('Cool response!');
    });
}

這可能會影響到this

另一方面,如果使用Redux,則應創建兩個操作。 例如, fetchAPI()APIfetched()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM