Во время работы над проектом я столкнулся с проблемой, когда мне нужно разделить код между двумя компонентами контейнера. Общий код заключался в обновлении хранилища с сервера. Сначала я создал функцию, которую использовал в компонентах контейнера для получения данных с сервера, и отправил действие с помощью функций обратного вызова.

function fetchDataFromServer(callBack){
this.callBack = callBack;
this.reFresh = function(id){
   axios.get("./api/getEmployee",{id: id})
   .then((res)=>{callBack(res.data);})
  }
}
export class ComponentA extends React.Coponent{
   constructor(props){
     super(props)
     this.state={employeeData:{}
     }
  }
refreshData(){
    let dataRefresher= fetchDataFromServer((empData)=>{
      this.props.refreshEmpData(empData);
    })
    dataRefresher.reFresh(this.props.user.id)
   }
render(){
  return(<div>
          <button onClick={()=>{this.refreshData()}}></button>
         <ShowEmployeeDataView empData={this.props.empData} /> 
       <div>);
   }
}
const mapStateToProps = state=>{
 retrun{
    user: state.user,
    empData: state.empData
 }
}
const mapDispatchToProps= dispatch=>{
 retrun{
    refreshEmpData: (empData)=> dispatch.refreshEmpData(empData)
 }
}
const ReduxComponentA = connect(mapStateToProps,mapDispatchToProps)(ComponentA);
export class ComponentB extends React.Coponent{
   constructor(props){
     super(props)
     this.state={employeeData:{}
     }
  }
postDataToServer(){
  // do some stuff..
  // post data to sever and refresh the store
refreshData();
 }
refreshData(){
    let dataRefresher= fetchDataFromServer((empData)=>{
      this.props.refreshEmpData(empData);
    })
    dataRefresher.reFresh(this.props.user.id)
  }
render(){
  return(<div>
          <button onClick={()=>{this.refreshData()}}></button>
         <ShowEmployeeDataView empData={this.props.empData} /> 
       <div>);
   }
}
const mapStateToProps = state=>{
 retrun{
    user: state.user,
    empData: state.empData
 }
}
const mapDispatchToProps= dispatch=>{
 retrun{
    // other Dispatch methods
    refreshEmpData: (empData)=> dispatch.refreshEmpData(empData)
 }
}
const ReduxComponentB = connect(mapStateToProps,mapDispatchToProps)(ComponentB);

Здесь мы видим, что компонент B должен знать о том, как обновить хранилище последними данными о сотрудниках, которые были изменены компонентом B.

Итак, как мы можем теперь заставить компонент B знать, как обновить хранилище. Для этого давайте следовать шаблону композиции, где мы можем создать компонент, не связанный с редукцией пользовательского интерфейса. Что мы можем включить и сослаться на него через «ref» и вызвать необходимые методы для обновления хранилища.

export class RefreshStoreComponent extends React.Coponent{
   constructor(props){
     super(props)
     this.state={employeeData:{}
     }
  }
refreshData(){
    let dataRefresher= fetchDataFromServer((empData)=>{
      this.props.refreshEmpData(empData);
    })
    dataRefresher.reFresh(this.props.user.id)
  }
render(){
  return(null);
   }
}
const mapStateToProps = state=>{
 retrun{
    user: state.user,
    empData: state.empData
 }
}
const mapDispatchToProps= dispatch=>{
 retrun{
    // other Dispatch methods
    refreshEmpData: (empData)=> dispatch.refreshEmpData(empData)
 }
}
const ReduxRefreshStoreComponent = connect(mapStateToProps,mapDispatchToProps, null,{forwardRef: true} )(RefreshSoteComponent);

Затем мы можем изменить существующие компоненты ComponentA и ComponentB, как показано ниже.

export class ComponentA extends React.Coponent{
   constructor(props){
     super(props)
     this.refreshHelper = React.createRef();
  }
postDataToServer(){
   //Do something other then componentB
   //Posintg comments along with some other data to server 
    // Then ask to refresh the store
    this.refreshHelper.current.refreshData();
 }
render(){
  return(<div>
            <ReduxRefreshStoreComponent ref={this.refreshHelper} />
             <input type="text" 
            onChange={(event)=> {
                  this.setState({comments: event.target.value});
             }} />          
            <button onClick={()=>{
               this.postDataToServer();
             }}>Submit Comments</button>
            <ShowEmployeeDataView empData={this.props.empData} /> 
       <div>);
   }
}
const mapStateToProps = state =>{
 retrun{
   comments: state.comments
 }
}
const ReduxComponentA = connect(mapStateToProps,null)(ComponentA);
export class ComponentB extends React.Coponent{
   constructor(props){
     super(props);
     this.state={
                comments:''
                }; 
     this.refreshHelper = React.createRef();
    }
postDataToServer(){
  // do some stuff..
  // post data to sever and refresh the store
 
  this.refreshHelper.current.refreshData();
 }
render(){
  return(<div>
         <ReduxRefreshStoreComponent ref={this.refreshHelper} />
         <input type="text" 
            onChange={(event)=> {
                  this.setState({comments: event.target.value});
          }} />          
         <button onClick={()=>{
          this.postDataToServer();
        }}>Submit Comments</button>
         <ShowEmployeeDataView empData={this.props.empData} /> 
       <div>);
   }
}
const mapStateToProps = state=>{
 retrun{
    comments: state.comments
 }
}
const ReduxComponentB = connect(mapStateToProps,null)(ComponentB);

Вывод:

Поскольку мы могли бы добиться этого, создав базовый компонент и унаследовав от него оба компонента. Но это не помогло бы нам, если бы мы захотели наследовать несколько базовых классов для использования поведения. Здесь мы используем композицию вместо наследования. Таким образом, мы можем использовать N классов, откуда мы хотим взять его поведение. Это также способствует повторному использованию кода и разделению ответственности… Happy Coding.. React Redux Rocks..