【发布时间】:2019-01-04 19:52:26
【问题描述】:
这是我的代码:
用户界面
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;
}
};
如果我运行上面的代码,我会得到这个错误:
错误:你不能在 reducer 执行时调用 store.getState()。 reducer 已经接收到状态作为参数。从顶部 reducer 向下传递,而不是从 store 中读取。
加载 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 |
应用程序/_this.setUser/
35 | // else this.setState({assignedWork: undefined});
36 | // });
37 | // }
> 38 | this.props.onLoad(this.state.user);
| ^ 39 | });
40 | };
41 |
所以我假设我的做法是错误的。但是如何将状态设置为等于数据库中的数据?我尝试在商店初始化中这样做,但它只是出错了。
【问题讨论】:
-
你不应该在减速器中使用
firebase.database().ref('Users').child(firebase.auth().currentUser.uid).child('level').set(action.payload).catch(e => console.log(e)); -
所以把它付诸行动?
-
是的,把它放在动作创建器(thunk)中,然后把它的结果保存在减速器中
标签: javascript reactjs firebase-realtime-database redux react-redux