Изменение состояния от другого редуктора в реакции - PullRequest
0 голосов
/ 17 января 2019

Я довольно новичок в реакции, так что это может быть глупый вопрос.

Я работаю над приложением, которое управляет RSS-фидами, поэтому структура всего моего приложения похожа на эту

<div className="App">
    <Header />
    <Feeds />
</div>

оба компонента имеют собственный редуктор и действия.

проблема возникает, когда я пытаюсь создать новый канал (фактически управляемый в редукторе каналов) из моего компонента заголовка. поэтому я должен получить доступ к состоянию feedsReducer из моего headerReducer.

Я не уверен, что делать дальше.

я должен получить доступ к редуктору каналов из компонента заголовка? (это также подразумевает, что feedsReducer должен знать мои действия заголовка)

Я добавлю код, чтобы прояснить проблему

index.js

import feedsReducer from './components/Feeds/FeedsReducer';
import headerReducer from './components/Header/HeaderReducer';
const rootReducer = {
    feeds:feedsReducer,
    header: headerReducer
};
const store = createStore(combineReducers(rootReducer));

Заголовок / Header.js

import { ADD_FEED } from './actions';

class Header extends Component {

    state = {
        feedUrl: ""
    };

    addFeed = () => {
        axios.post(
            '/feeds/add',
            {
                url: 'myNewRssFeed.com'
            })
            .then(feed => {
                //this is calling the HeaderReducer
                this.props.addFeed(feed.data);
            })
            .catch(err => console.log(err));
    }

}

const mapDispatchToProps = dispatch => {
    return {
        addFeed: (feed) => dispatch({ type: ADD_FEED, payload: { feed } })
    };
};

export default connect(null, mapDispatchToProps)(Header);

Заголовок / actions.js

export const ADD_FEED = "ADD_FEED";

HeaderComponent / HeaderReducer.js

const reducer = (state, action) => {
    const newState = {
        ...state
    }
    switch (action.type) {
        case storeActions.ADD_FEED:
            // at this point newState.feeds doesn't exist because it's part from the FeedsReducer
            newState.feeds = newState.feeds.push(action.payload.feed);
            break;
    }
    return newState;
}

Ленты / FeedsReducer.js

const initialState = {
    feeds: []
}
const reducer = (state = initialState, action) => {
    const newState = {
        ...state
    }
    switch (action.type) {
        //this action is commented because was recently moved to the headerComponent/actions.js
        /* case storeActions.ADD_FEED:
            newState.feeds = newState.feeds.push(action.payload.feed);
            break; */
        case storeActions.LOAD_FEEDS:
            newState.feeds = action.payload.feeds;
            break;
    }
    return newState;
}

Спасибо за совет.

1 Ответ

0 голосов
/ 17 января 2019

Не думаю, что вам нужен доступ к редуктору. Функция Reducer будет обновлять хранилище в зависимости от действия, которое она прослушивает. Вот пример:

import * as constants from 'constantpathhere';

export function feedReducer(state = INITIAL_STATE, action) {
   const { type, payload } = action;
   switch(type) {
      case constants.ADD_FEED: // listen to ADD_FEED action
         return {... state, data: payload };
      case constants.LOAD_FEEDS: // listen to LOAD_FEEDS
         return {...state, loading: true }
      ...
      default: 
         return state;

   }

}

export function headReducer(state = INITIAL_STATE, action) {
   const { type, payload } = action;
   switch(type) {
      case constants.ANY_ACTION: // listen to ADD_FEED action
         return {... state, data: payload };
      case constants.ANY_OTHER_ACTION_LOADING: // listen to LOAD_FEEDS
         return {...state, loading: true }
      ...
      default: 
         return state;

   }

}

//ACTIONS

export function loadFeeds() {
   return {
     type: constants.LOAD_FEEDS
   }
}

export function addFeed(payload) {
  return {
    type: constants.ADD_FEED,
    payload
  }
}

export function triggerAnyAction(payload) {
   return {
     type: constants.ANY_ACTION,
     payload
   }
}

Эти действия выше могут быть отправлены из любого компонента, будь то Header или Feeds, только редуктор (ы), прослушивающие это конкретное действие, обновят хранилище.

Вкратце, вам нужно только знать, какое действие куда направлять, и только перечисление редуктора к этому действию будет делать то, что вы ему указали

...