As a note, I came from your post: https://dannyherran.com/2017/03/react-redux-mobx-takeaways/
This is wrong from the start. Refs should not be shared between components because that couples them. Components should be designed completely decoupled from one another and react based on state given to them.
The problem is that the ref tells you nothing about the state of the component itself, you don't know if it mounted, you don't know if it even exists, so you're playing with something volatile.
So let's decouple everything and leverage the power of react/redux properly, all code should be organized in this manner:
1. Reducer:
Reducer will maintain the display state of the alert.
Any component in your entire application now has access to it, independent of refs, so it won't matter if the component actually exists or not.
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. Action and Async Action:
Action to adjust the display setting of the alert, and async action to perform the fetch and produce the correct result.
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. Connected Component:
The connected component. No need to share refs, the ref will be used, but the component will react to its given props and set the Alert accordingly.
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);
this.props.fetchSomething.then(() => this._alert.show('Cool response!')
you just have to make sure that you are returning the promise in the action. – Grolierredux-promise-middleware
or something similar – Absorb