在 Redux 中设置应用挂载的商店状态

亚历克斯·艾恩赛德

这是我的代码:

用户界面

export default class App extends Component {
    constructor(p) {
        super(p);
        this.state = {user: null};
    }

    setUser = () => {
        const {uid} = firebase.auth().currentUser;
        firebase.database().ref('Users').child(uid).on('value', r => {
            const user = r.val();
            this.setState({user: user});
            this.props.onLoad(this.state.user); // This is the problem
        });
    };

    componentWillMount() {
        if (firebase.auth().currentUser) {
            this.setUser();
        }
        firebase.auth().onAuthStateChanged(async () => {
            if (!firebase.auth().currentUser) {
                return null;
            }
            this.setUser();
        });
    }


    render() {
        return (
            <div className="App">
                <Nav/>
            </div>
        );
    }
}

容器

const mapStateToProps = state => ({user: state.user});
const mapDispatchToProps = dispatch => ({
    onLoad(user) {
        dispatch(setUser(user))
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(App);

所以我想要做的是在组件安装后立即设置一个商店。它一直有效,直到在此应用程序中进行更改。如果我更改数据库中的数据,我的应用程序中的数据就会毫无问题地更新。

如果我尝试运行这个:

容器:

import {setLevel} from "../../../../../actions";
import LevelSelectUI from '../../../ui/mainUI/levelSelectUI/LevelSelectUI';

const mapStateToProps = (state, props) => ({
    user: props.user
});

const mapDispatchToProps = dispatch => ({
    onLevelChange(uid, value) {
        dispatch(setLevel(uid, value));
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(LevelSelectUI)

用户界面

export default ({user = {}, onLevelChange = f => f}) => {
    const lvls = [{
        db: 'Podstawówka',
        text: 'PODSTAWOWA',
    }, {
        db: 'Gimnazjum',
        text: 'GIMNAZJALNA',
    }, {
        db: 'Liceum',
        text: 'ŚREDNIA',
    }];
    let options = [];
    if (!user.level) {
        options.push(<option key={options.length} value={null}>WYBIERZ POZIOM</option>)
    }
    options = options.concat(lvls.map((lvl, i) => {
        return (
            <option key={(i + 1) * 2} value={lvl.db}>{`SZKOŁA ${lvl.text}`}</option>
        )
    }));
    return (
        <select value={user.level}
                onChange={e => onLevelChange(e.target.value)}>
            {/*onChange={(e) => console.log(e.target.value)}>*/}
            {options.map(opt => opt)}
        </select>
    )
}

行动:

export const setLevel = (value = '') => ({
    type: C.SET_LEVEL,
    payload: value,
});

减速器:

export const level = (state = {}, action) => {
    switch (action.type) {
        case C.SET_LEVEL:
            return firebase.database().ref('Users').child(firebase.auth().currentUser.uid).child('level').set(action.payload).catch(e => console.log(e));
        default:
            return state;
    }
};

如果我运行上面的代码,我会收到这个错误:

错误:您不能在减速器执行时调用 store.getState()。减速器已经收到状态作为参数。从顶部减速器传递它而不是从商店读取它。

onLoad src/AppContainer.jsx:8

   5 | const mapStateToProps = state => ({user: state.user});
   6 | const mapDispatchToProps = dispatch => ({
   7 |     onLoad(user) {
>  8 |         dispatch(setUser(user))
   9 |     }
  10 | });
  11 | 

App/_this.setUser/< src/AppUI.jsx:38

  35 |         //         else this.setState({assignedWork: undefined});
  36 |         //     });
  37 |         // }
> 38 |         this.props.onLoad(this.state.user);
     | ^  39 |     });
  40 | };
  41 | 

所以我假设我的做法是错误的。但是如何将状态设置为等于数据库中的数据?我尝试在商店初始化时这样做,但它只是出错了。

亚历克斯·艾恩赛德

我最终删除了减速器和动作,只是这样做了:

容器:

const mapStateToProps = (state, props) => ({
    user: props.user
});

const mapDispatchToProps = () => ({
    onLevelChange(value) {
        firebase.database().ref('Users').child(firebase.auth().currentUser.uid).child('level').set(value).catch(e => console.log(e));
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(LevelSelectUI)

用户界面:

export default ({user = {}, onLevelChange = f => f}) => {
    const lvls = [{
        db: 'Podstawówka',
        text: 'PODSTAWOWA',
    }, {
        db: 'Gimnazjum',
        text: 'GIMNAZJALNA',
    }, {
        db: 'Liceum',
        text: 'ŚREDNIA',
    }];
    let options = [];
    if (!user.level) {
        options.push(<option key={options.length} value={null}>WYBIERZ POZIOM</option>)
    }
    options = options.concat(lvls.map((lvl, i) => {
        return (
            <option key={(i + 1) * 2} value={lvl.db}>{`SZKOŁA ${lvl.text}`}</option>
        )
    }));
    return (
        <select value={user.level}
                onChange={e => onLevelChange(e.target.value)}>
            {/*onChange={(e) => console.log(e.target.value)}>*/}
            {options.map(opt => opt)}
        </select>
    )
}

感谢Manjeet Singh 的帮助

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类常见问题

在Redux Reducer中读取商店的初始状态

来自分类Dev

在Redux中更改状态

来自分类Dev

Redux中的应用程序与本地状态

来自分类Dev

Websocket事件在React应用中收到旧的Redux状态

来自分类Dev

Redux中状态对象的结构

来自分类Dev

在Redux中未正确调用在商店中应用中间件的reducer

来自分类Dev

在React.js / Redux应用程序中设置默认状态

来自分类Dev

在Redux中处理长寿状态

来自分类Dev

在Redux中覆盖整个状态

来自分类Dev

清除Redux商店

来自分类Dev

Redux:无法使用商店

来自分类Dev

在Redux中更新对象的状态

来自分类Dev

react-redux应用程序中的状态对象结构

来自分类Dev

如何在带有Redux应用程序的MERN中单击时将状态设置为“空”?

来自分类Dev

Redux包装的组件如何设置状态?

来自分类Dev

Redux不更新商店

来自分类Dev

就Redux而言,视图渲染是什么触发商店设置初始状态的?还是商店最初首先成立?

来自分类Dev

在React.js / Redux应用程序中设置默认状态

来自分类Dev

在Redux中处理长寿状态

来自分类Dev

Redux:在商店状态更新时重新渲染子级

来自分类Dev

反应-redux。如何在第一次应用程序渲染时获取更新的商店状态

来自分类Dev

React + Redux:商店更新时如何更新状态

来自分类Dev

我可以将商店的状态与 react-redux 中的组件绑定吗?

来自分类Dev

从 redux 商店加载 pdf

来自分类Dev

无法在 redux 商店中设置状态

来自分类Dev

redux 中的状态解构问题

来自分类Dev

当 redux 更改商店中的状态时,我的 reactJS 应用程序不会重新呈现

来自分类Dev

组件中的 Redux mapStateToProps 状态

来自分类Dev

在 Redux 中更改状态的位置?

Related 相关文章

热门标签

归档