@igotDiamonds

Сохранить state компонента при роутинге?

Привет, в общем есть такой компонент который рендерится по 2ум путям:
1) /users/
2)/users/:id/edit

В компоненте реализован поиск по списку, после того как фильтрация сработала если кликнуть на любой элемент списка то произойдет роутинг на /users/:id/edit и весь компонент ререндерится и теряет состояние, я попробовал решить проблему через Redux но при повторном монтировании компонента стейт почему то не берется из стора...

import React, { Fragment } from 'react';
import Component from 'cms/services/component';
import { Link } from 'react-router-dom';
import Card, { CardActions, CardAction, CardHeader, CardTitle, CardBody }
    from 'cms/components/common/card';
import { IconButton } from 'cms/components/common/icon';

import { connect } from 'react-redux';
import { bindActionCreators }
    from 'redux';
import { Widget } from 'cms/components/pages/structure/dashboard';

import * as common from 'cms/actions/common';
import * as users from 'cms/actions/users';

import UserDetail from './user-detail';

class UsersList extends Component {

    constructor(props) {
        super(props);

        this.state = {
            search: {
                q: ""
            },
            page: 1
        };

        this.props.common.setTitle('Users');
        this.props.api.users.all(this.state.search);
        this.props.common.setBreadcrumbs({
            '/': 'Admin',
            [props.match.url]: 'Users'
        });
    }

    componentDidUpdate(prevProps, prevState) {
        if (this.state.search !== prevState.search) {
            this.props.api.users.all(this.state.search);
        }
    }

    componentDidMount() {
        console.log('Did mount yay! ')
        this.setState((state, props) => {
            console.log('This is the setstate that i want to work')
            return { 
                search: this.props.searchState
            }
        }, ()=>{console.log(this.state)})
    }

    componentWillUnmount() {
        this.props.api.users.search(this.state.search.q);
    }

    onSearchLastName(search) {
        console.log('eventually updated state idk why')
        this.setState((state) => {
            return {
                ...state,
                search: {
                    q: search
                },      
                page: 1
            }
        });
    }

    onLoadMore() {
        this.setState({
            search: {
                ...this.state.search,
                page: this.state.search.page + 1
            }
        });
    }

    renderHeaderContent = (props) => {

        const inputs = ['first_name_cont', 'last_name_cont', 'email_cont'];
        return (
            <CardTitleWithSearch {...props} inputs={inputs} onChange={search => this.onSearchLastName(search)} />
        )
    }

    render() {
        const id = this.props.match.params.id,
            details = id ?
                this.data.payload.find(u => u.id == id) :
                null;

        const getTitle = (user) => {
            return `${user.first_name || ''} ${user.last_name || ''}`.trim();
        };


        const getText = (u) => {
            return u.email + (
                u.phone ? '; tel: ' + u.phone : ''
            );
        };

        return (
            <div className="row">
                <div className="col-xs-12">
                    {/* <CardTitleWithSearch {...this.props} inputs={searchInputs} onChange={search => this.onSearchLastName(search)} /> */}
                    {this.renderHeaderContent()}
                </div>
                <div className={`col-xs-${details ? '4' : '12'}`}>
                    <Widget
                        title="Users"
                        data={this.data}
                        itemLink={u => `/users/clients/${u.id}/edit`}
                        itemTitle={getTitle}
                        itemText={getText}
                        onLoadMore={() => this.onLoadMore()}
                    />
                </div>
                {details && (
                    <div className="col-xs-8">
                        <UserDetail
                            user={details}
                        />
                    </div>
                )}
            </div>
        );
    }

    get data() {
        return this.props.users;
    }
}

CardTitleWithSearch.defaultProps = {
    onChange() { }
}

function CardTitleWithSearch(props) {
    const [searchMode, setSearchMode] = React.useState(true);
    const [search, setSearch] = React.useState('');

    function toggle() {
        setSearchMode(!searchMode);
        setSearch('');
    }

    function onChange(ev) {
        const value = ev.target.value;
        setSearch({
            ...search,
            [ev.target.name]: value,
        });
    }

    React.useEffect(() => {
        props.onChange(search)
    }, [search])

    return (
        <Card>
            <CardHeader>
                Search users by
            </CardHeader>
            <CardBody style={{
                'display': 'flex',
                'justifyContent': 'space-between'
            }}>
                {searchMode ? props.inputs.map(item => {
                    let placeholder = item.replace('_', ' ').replace('_cont', '').replace('cont', '');
                    placeholder = item.charAt(0).toUpperCase() + placeholder.slice(1);
                    return (
                        <div style={{
                            'width': '30%',
                            'height': '40px'
                        }}>
                            <input
                                name={item}
                                type="text"
                                class="form-control"
                                placeholder={placeholder}
                                value={search.item}
                                onChange={onChange}
                            />
                        </div>)
                }
                ) : (
                        props.title
                    )}
            </CardBody>
        </Card>
    )
}


export default connect(({ api }) => ({
    users: api.users.list,
    searchState: api.users.search
}), (dispatch) => {
    return ({
        common: bindActionCreators(common, dispatch),
        api: {
            users: bindActionCreators(users, dispatch)
        }
    })
})(UsersList);
  • Вопрос задан
  • 159 просмотров
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы