Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.10.2024, 19:16
Кандидат Javascript-наук
Отправить личное сообщение для Raadsert Посмотреть профиль Найти все сообщения от Raadsert
 
Регистрация: 09.12.2021
Сообщений: 102

Ререндер компонентов с Redux
Подскажите пожалуйста, как изменение данных в Redux вызывают ререндер того компонента где эти данные используются?

Смотрел как устроена работа Redux в видео "https://youtu.be/sLCfWSle5Jw?si=8b2M6WBCMzdgp1cL", но там не рассказывают о том как вызывается ререндер компонента после изменения данных.
Вот весь код из видео:
const createStore = (reducer) => {
    let state = reducer(undefined, { type: '__INIT__' });
    let subscribers = [];

    return {
        getState: () => state,
        dispatch: action => { 
            state = reducer(state, action);
            subscribers.forEach(cb => cb());
        },
        subscribe: (cb) => subscribers.push(cb),
    };
};

const initialState = {
    count: 0,
};

const INCREMENT = 'INCREMENT';

const increment = count => ({
    type: INCREMENT,
    payload: count,
});

const countReducer = (state = initialState, action) => {
    switch (action.type) {
        case INCREMENT:
            return {
                ...state,
                count: state.count + action.payload,
            };
        
        case 'DECREMENT':
            return {
                ...state,
                count: state.count - action.payload,
            };

        default:
            return {
                ...state,
            };
    }
};

const initialUSerState = {
    users: [],
};

const userReducer = (state = initialUSerState, action) => {
    switch (action.type) {
        case 'SUCCESS':
            return {
                ...state,
                users: action.payload,
            };

        default:
            return {
                ...state,
            };
    }
};

// const reducer = (state, action) => {
//     return {
//         userState: userReducer(state.userState, action),
//         countState: countReducer(state.countState, action),
//     };
// };

const combineRedcuers = (reducersMap) => {
    return (state, action) => {
        const nextState = {};

        Object.entries(reducersMap).forEach(([key, reducer]) => {
            nextState[key] = reducer(state ? state[key] : state, action);
        });

        return nextState;
    };
};

const rootReducer = combineRedcuers({ userState: userReducer, countState: countReducer });

// const store = createStore(rootReducer);

// console.log(store.getState());

// // store.subscribe(() => console.log('change'));

// store.dispatch(increment(3));
// store.dispatch({ type: 'DECREMENT', payload: 1 });
// store.dispatch({ type: 'SUCCESS', payload: [{ name: 'user' }] });

// console.log(store.getState());

const logger = store => dispatch => action => {
    console.log(action.type);
}

const thunk = store => dispatch => action => {
    if (typeof action === 'function') {
        return action(store.dispatch, store.getState);
    }

    return dispatch(action);
};

const applyMiddleware = (middleware) => {
    return (createStore) => {
        return (reducer) => {
            const store = createStore(reducer);
            return {
                dispatch: action => middleware(store)(store.dispatch)(action),
                getState: store.getState,
            }
        }
    }
};

const init = {
    isLoading: false,
}

const reducerNew = (state = init, action) => {
    switch (action.type) {
        case 'STARTED':
            return {
                ...state,
                isLoading: true,
            };

        case 'SUCCESS':
            return {
                ...state,
                isLoading: false,
            };

        default:
            return {
                ...state,
            }
    }
}

const someAction = () => {
    return async (dispatch) => {
        dispatch({ type: 'STARTED' });

        await new Promise(resolve => setTimeout(() => resolve(), 2000));

        dispatch({ type: 'SUCCESS' });
    }
}

const createStoreWithMiddleware = applyMiddleware(logger)(createStore);
const storeWithMiddle = createStoreWithMiddleware(reducerNew);

console.log(storeWithMiddle.getState());

storeWithMiddle.dispatch({ type: 'SUCCESS' });

console.log(storeWithMiddle.getState());

setTimeout(() => {
    console.log(storeWithMiddle.getState());
}, 5000);
Ответить с цитированием
  #2 (permalink)  
Старый 21.10.2024, 20:38
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

видео - про собственно редукс как таковой.

а тебе надо разобраться как работает хук useSelector из пакета react-redux. Это уже "совсем другая история". Под капотом - useSyncExternalStore
Ответить с цитированием
  #3 (permalink)  
Старый 25.10.2024, 02:45
Кандидат Javascript-наук
Отправить личное сообщение для Raadsert Посмотреть профиль Найти все сообщения от Raadsert
 
Регистрация: 09.12.2021
Сообщений: 102

Сообщение от Alexandroppolus Посмотреть сообщение
видео - про собственно редукс как таковой.

а тебе надо разобраться как работает хук useSelector из пакета react-redux. Это уже "совсем другая история". Под капотом - useSyncExternalStore
Не. Там Context API под капотом.
Ответить с цитированием
  #4 (permalink)  
Старый 25.10.2024, 10:24
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Context API это понятно. Но там в контексте просто хранится стор. Т.е. ссылка на объект в контексте - постоянная, и ререндеры с этим никак не связаны. Иначе на любое изменение в редуксе, ререндерились бы все компоненты, которые используют этот контекст (все, в которых вызывается хуки useSelector/useDispatch/useStore). А это, разумеется, не так.

Последний раз редактировалось Alexandroppolus, 25.10.2024 в 10:26.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Локальное подключение компонентов vue? Lodas Библиотеки/Тулкиты/Фреймворки 0 11.04.2020 22:42
Redux и React. Перенос типов из actions в reducer и логики из reducer в component R2R Библиотеки/Тулкиты/Фреймворки 0 28.04.2019 22:07
Frontend Developer (JavaScript/HTML/CSS, React, Redux, Webpack), Москва. 160 гросс. Metelitsa Работа 0 23.08.2017 17:19
Можно ли в Redux использовать EventEmitter? yazonnile Общие вопросы Javascript 7 06.04.2016 22:51
Наболело до жути! Определение размеров компонентов demoniqus jQuery 2 03.11.2012 15:19