我在我的本机应用程序Switcher组件中使用nachos-ui
在我的configScreen.js中,如下所示:
<Switcher
onChange={((difficulty) => this.onLevelSelect(difficulty) )}
defaultSelected={this.props.difficulty} >
<TabButton value='medium' text='medium' />
<TabButton value='easy' text='easy'/>
</Switcher>
,我有一个重置按钮,可以从商店重置this.props.difficulty的值。
一切正常,商店会重置,并且值恢复正常,但切换器始终指示旧值,除非我移至另一个屏幕,然后转到configScreen.js,这时更改生效(即:defaultSelected的值)表示商店的价值。
有人可以指导我如何使用componentShouldUpdate或 componentWillRecieveProps ??
action / index.js:
exports.changeLevel = (select) => {
return {
type: 'CHANGE_LEVEL',
select
}
}
exports.resetGame = () => {
return{
type: 'RESET_GAME',
}
}
reducer / index.js:
module.exports = ( state = {}, action ) => {
switch(action.type) {
case 'RESET_GAME' :
return {
...state,
difficulty: 'easy',
}
case 'CHANGE_LEVEL':
return {
...state,
difficulty: action.select
}
default:
return state
}
}
store / index.js:
import { createStore, compose } from 'redux';
import { AsyncStorage } from 'react-native';
import { persistStore, autoRehydrate } from 'redux-persist';
import reducer from '../reducer';
const defaultState = {
difficulty: 'easy',
}
export const configureStore = (intialState = defaultState, action) =>{
var store = createStore(reducer, intialState,compose(
autoRehydrate()
));
persistStore(store, {storage: AsyncStorage});
return store;
}
configScreen.js:
import React, { Component } from 'react';
import {connect} from 'react-redux';
import { View, Text, StyleSheet, ImageBackground, TouchableOpacity, Dimensions } from 'react-native';
import { Container, Header, Content, Card, CardItem, Button, Icon, Left, Body } from 'native-base';
import { AdMobBanner } from "expo";
import DropdownAlert from 'react-native-dropdownalert';
import {changeLevel, reset, resetGame} from '../actions';
import {Switcher, TabButton, themeManager} from 'nachos-ui';
import { configureStore } from '../store';
const buttonTheme = themeManager.getStyle('TabButton');
const newButtonTheme = {
...buttonTheme,
BUTTON_BACKGROUND:'#fff',
BUTTON_BORDER_WIDTH:1,
BUTTON_BORDER_COLOR:'#4bb29e',
BUTTON_BORDER_RADIUS:5,
BUTTON_HEIGHT:25,
BUTTON_WIDTH: 10,
BUTTON_FONT_COLOR:'black',
BUTTON_FONT_SIZE:14,
BUTTON_FONT_WEIGHT:'normal',
BUTTON_FONT_FAMILY:'jf',
BUTTON_SELECTED_BACKGROUND:'#4bb29e',
BUTTON_SELECTED_FONT_COLOR:'white',
BUTTON_SELECTED_BORDER_COLOR:'#4bb29e',
}
themeManager.setSource('TabButton', () => (newButtonTheme))
const screenWidth = Dimensions.get('window').width / 12;
class AboutScreen extends Component {
_goBack = () => {
this.props.navigation.goBack(null)
}
onClose(data) {
// data = {type, title, message, action}
// action means how the alert was closed.
// returns: automatic, programmatic, tap, pan or cancel
}
// RESET THE STORE HERE
onReset() {
this.gameReset()
console.log(configureStore().getState())
}
onLevelSelect(selected) {
this.props.dispatch(changeLevel(selected))
}
gameReset() {
this.props.dispatch(resetGame())
}
render() {
return (
<Container style={{backgroundColor: 'white',}}>
<Content>
<Card>
<CardItem>
<Switcher
onChange={((difficulty) =>
this.onLevelSelect(difficulty) )}
defaultSelected={this.props.difficulty}
>
<TabButton value='medium' text='medium' />
<TabButton value='easy' text='easy'/>
</Switcher>
<CardItem>
<Button title='reset' onPress={() => this.gameReset()} />
</Card>
</Content>
</Container>
);
}
}
function mapStateToProps(state) {
return {
difficulty: state.difficulty,
}
}
function mapDispatchToProps(dispatch) {
return {
changeLevel: () => dispatch(changeLevel(this.props.difficulty))
}
}
export default connect(mapStateToProps)(AboutScreen)
答案 0 :(得分:1)
您不应该使用componentWillRecieveProps
,因为它将很快被弃用。
会被getDerivedStateFromProps (注意,与componentWillRecieveProps
的工作方式不同)代替。
此外,如果正确使用它,则不必使用这些生命周期方法,因为
componentWillRecieveProps(nextProps)'s
的目的是/曾经是update state on props change。如果您需要更多帮助,请发布更多代码:)
更新
一些注意事项:
componentWillUpdate(nextProps, nextState) {
if(nextProps.difficulty !== this.props.difficulty ){
this.setState({difficulty: this.props.difficulty})
}
}
您要在这里实现什么?在这里执行this.setState({...});
是非常危险的。因为您可以trigger an endless loop of rerenders。
同样,您什么也不做,只是将组件的本地状态分配给旧的道具。而且您没有在应用程序中的任何地方使用this.state.difficulity
。实际上,您只是触发了另一个重新渲染(无论如何都会发生)。
还:
function mapDispatchToProps(dispatch) {
return {
changeLevel: () => dispatch(changeLevel(this.props.difficulty))
}
}
您无权访问this
,因为它在类上下文之外。
您需要将this.props.difficulty
(尽管您正在传递选择的内容)作为分派调用的参数。您没有在此处连接resetGame()
,您应该这样做。最后,尝试在分派中使用不同的命名:
function mapDispatchToProps(dispatch) {
return {
onDispatchChangeLevel: (difficulty) => dispatch(changeLevel(difficulty)),
onDispatchResetGame: () => dispatch(resetGame())
}
}
然后,当您调度changeLevel时,将其传递给this.props.difficulty
并使用连接的调度而不是this.props.dispatch
:
onLevelSelect(selected) {
this.props.onDispatchChangeLevel(selected)
}
gameReset() {
this.props.onDispatchResetGame();
}
最后:
我不确定这一点:
<Switcher
onChange={((difficulty) => this.onLevelSelect(difficulty) )}
defaultSelected={this.props.difficulty}>
通常,您onChange
传递一个事件,并且您将其视为难易度字符串easy
。但是正如我所说,我不知道Switcher的工作原理。
希望这会很有用,我认为错误出在我评论的地方。否则我可以再看看:)
答案 1 :(得分:0)
问题出在nachos-ui的切换器组件上。
react-native-element buttonGroup或内置组件解决了该问题,
nachos-ui:v0.2.0-beta.1
react-native:facebook v27的分支版本 expo SDK:v28