@shading

React-redux не перерисовывается компонент при изменении state?

Ссылка на гит - https://github.com/Shading29/tosterr/blob/master/s...
При изменении стейта search не перерисовывается таблица.
Стейт точно изменяется корректно
Судя по всему я пошёл не тем путем)
  • Вопрос задан
  • 2367 просмотров
Пригласить эксперта
Ответы на вопрос 2
Devilz_1
@Devilz_1
Frontend-Developer
Ваша логика здесь такая:

Производя ввод каких-то символов, вызывается функция filterUsers, которая в свою очередь диспатчит вводимое значение в store, заменяя каждый раз параметр search. Каждый раз, когда вызывается dispatch происходит перерендер того состояния, который меняется в зависимости от диспатча. В вашем примере, вы обновляете состояние параметра search, когда параметр users сохраняет своё состояние с того момента, когда вы последний раз диспатчили его (т.е. вызывали функцию loadUsers), потому, что функция filterUsers ссылается на кейс USERTABLE_FILTER_USERS, а к кейсу, который меняет непосредственно состояние параметра users (USERSTABLE_LOAD_USERS) он не обращается.

Попробуйте так. Решение конечно не идеально, но Вы должны увидить разницу. Замените свой кейс USERTABLE_FILTER_USERS, на тот, что внизу.

case USERTABLE_FILTER_USERS:
                return {
                    ...state,
                    search: action.payload,
                    users: filteredUsers(state.users)
                }
Ответ написан
Комментировать
@camelCaseVlad
Посмотрел на вашу репу:

Вот что сделал я.

Во первых, вы не настроили store и редукс дев-тулз.

Я сделал это в вашем индексе, однако рекомендую вынести данный функционал в отдельный файл (установите недостающие пакеты):

// src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { applyMiddleware, compose, createStore } from 'redux';
import { createLogger } from 'redux-logger';
import rootReducer from "./store/reducers";
import { Provider } from "react-redux"
import {BrowserRouter} from "react-router-dom";

function configureStore(initialState) {
  const windowExist = typeof window === 'object';
  const loggerMiddleware = createLogger({
    colors: {
      title: (color) => windowExist && color,
      prevState: (color) => windowExist && color,
      action: (color) => windowExist && color,
      nextState: (color) => windowExist && color,
      error: (color) => windowExist && color
    }
  });
  const composeEnhancers = (windowExist &&
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || // eslint-disable-line no-underscore-dangle
    compose;
  return createStore(
    rootReducer,
    initialState,
    composeEnhancers(
      applyMiddleware(loggerMiddleware),
    )
  );
}



const application = (
    <BrowserRouter>
        <Provider store={configureStore()}>
            <App/>
        </Provider>
    </BrowserRouter>
)

ReactDOM.render( application , document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();


Функционал filteredUsers в папке reducers не нужен. У вас уже есть массив с юзерами, можете работать с ним в компоненте напрямую.

// src/store/UsersTable/reducers.js

import {
    USERSTABLE_LOAD_USERS,
    USERTABLE_FILTER_USERS
} from "./actions";

const defaultState = {
    users: [],
    isLoading: true,
    search: '',
}



export const userstableReducer = (state = defaultState, action) => {
        switch(action.type) {
            case USERSTABLE_LOAD_USERS:
                return {
                    ...state,
                    users: action.payload,
                    isLoading: false
                }
            case USERTABLE_FILTER_USERS:
                return {
                    ...state,
                    search: action.payload
                }
            default: return state
        }

}


Теперь к вопросу.

У вас уже есть массив, поработав напрямую с котором можно отражать нужные ячейки
import React from "react"
import "./userstable.css"

export default class UsersTable extends React.Component {
    render() {
        const { users, filterUsers, searchValue } = this.props
        const filteredUsers = users && users.filter(user => {
            const fullName = `${user.name} ${user.surname}`;
            return fullName.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1;
        });
        return (
            <React.Fragment>
                <input
                    onChange={event => filterUsers(event.target.value)}
                />
                    <table>
                        <thead>
                            <tr>
                                <th>Имя</th>
                                <th>Фамилия</th>
                                <th>Город</th>
                                <th>IP</th>
                            </tr>
                        </thead>
                        {<b>filteredUsers</b>.map(user => {
                            return (
                                <tbody key={user.id}>
                                <tr>
                                    <td> {user.name}</td>
                                    <td> {user.surname}</td>
                                    <td> {user.city}</td>
                                    <td> {user.lastloginfromip}</td>
                                </tr>
                                </tbody>

                            )
                        })}
                    </table>
            </React.Fragment>
        )
    }
}

5dfa91f33fd2a343028976.png
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы