这是我的代码:
UI
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)
UI
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 |
所以我认为我的做法是错误的。但是,如何将状态设置为等于数据库中的数据?我尝试在商店初始化中执行此操作,但是它只是出错了。
答案 0 :(得分:1)
我最终删除了reducers和actions,并且这样做了:
容器:
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)
UI:
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的成就