2016-08-30 41 views
1

在iOS React Native + Redux中,我使用以下Switch組件(https://facebook.github.io/react-native/docs/switch.html)。它首先被設置爲關閉,但是當打開時,它立即自行關閉。可能是什麼問題?React Native + Redux:爲什麼在切換爲true後切換立即回到假?

這是我的設立:

<Switch 
    onValueChange={this._handleSwitch} 
    value={switch.currentValue} 
/> 

而觸發的動作是:

_handleSwitch(value) { 
    this.props.actions.triggerSwitch(value) 
    } 

,措施是:

export function triggerSwitch(value) { 
    return { 
    type: TRIGGER_SWITCH, 
    currentValue: value 
    } 
} 

而在減速:

const initialState = { 
    currentValue: false 
} 

function switchReducer(switch = initialState, action) { 
    switch(action.type) { 
    case TRIGGER_SWITCH: 
     return { 
     currentValue: action.currentValue 
     } 

    default: 
     return switch 
    } 
} 

export default switchReducer 

謝謝!

+0

測試一下默認情況下,好像它被稱爲'TRIGGE之後R_SWITCH' – Maxx

+0

使用'_handleSwitch =(value)=> {this.props.actions.triggerSwitch(value)}' – stereodenis

+0

@Maxx是不是我的redux設置不正確?請看看這個http://stackoverflow.com/questions/39235637/react-native-why-isnt-redux-correctly-updating-the-state –

回答

0

您是否正確地綁定了_handleSwitch函數? this.props.actions.triggerSwitch(value)調度好嗎?

使用redux-logger來檢查您在每個階段的狀態和操作,並確保您的組件在切換後接收到正確的值。

+0

是的,在構造函數中,我確實使用了redux-logger並正確顯示prev和next狀態。但是當我觸發它時,它本身就會回到「錯誤」的位置。 –

+0

是不是我的redux設置不正確?請看看這個http://stackoverflow.com/questions/39235637/react-native-why-isnt-redux-correctly-updating-the-state –

0

如果您正在編寫對諸如class Blah extends React等ES6組件樣式的反應,則需要使用.bind(this)來更改運行時範圍。

constructor(props) { 
    super(props) 
    this._handleSwitch = this._handleSwitch.bind(this); 
} 

這可能工作。或者關注@stereodenis的評論。這樣做,但每次組件的重新渲染,它都會創建方法。

+0

我知道並已經定義它,但仍然沒有'工作。 –

+0

是不是我的redux設置不正確?請看看這個http://stackoverflow.com/questions/39235637/react-native-why-isnt-redux-correctly-updating-the-state –

-1

我遇到過類似的問題(與redux無關)。對於我來說,當開關被放置在一個ListView中並且ListView的數據源沒有在Switch的onValueChange中更新時,開關立即變回。
演示:https://rnplay.org/apps/tb6-fw
修正:https://rnplay.org/apps/FfoVmg

鏈接不工作了,所以這裏是開關ListView中不能正常工作代碼:

import React, { Component } from 'react'; 
import { 
    AppRegistry, 
    StyleSheet, 
    Text, 
    View, 
    ListView, 
    Switch 
} from 'react-native'; 


export default class SwitchTest extends Component { 

    constructor(props) { 
    super(props); 

    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 

    this.state = { 
     switch1Value: false, 
     switch2Value: false, 
     dataSource: ds.cloneWithRows([{ data: 'some row data...'}]), 
    }; 
    } 

    render() { 
    return (
     <View style={styles.container}> 
     <Switch 
      value={this.state.switch1Value} 
      onValueChange={value => this.setState({ switch1Value: value })} 
     /> 
     <View style={styles.listWrapper}> 
      <ListView 
      dataSource={this.state.dataSource} 
      renderRow={(rowData) => (
       <View style={styles.row}> 
       <Text>{rowData.data}</Text> 
       <Switch 
        value={this.state.switch2Value} 
        onValueChange={value => this.setState({ switch2Value: value })} 
       /> 
       </View> 
      )} 
      /> 
     </View> 
     </View> 
    ); 
    } 
} 

const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    justifyContent: 'center', 
    alignItems: 'center', 
    backgroundColor: '#F5FCFF', 
    }, 
    listWrapper: { 
    height: 100, 
    padding: 10 
    }, 
    row: { 
    flexDirection: 'row', 
    alignItems: 'center' 
    } 
}); 

AppRegistry.registerComponent('SwitchTest',() => SwitchTest); 

的解決方法是把內部數據源switch2Value狀態並更新Switch的onValueChange內的dataSource。

// ... 

this.state = { 
    switch1Value: false, 
    dataSource: ds.cloneWithRows([{ data: 'some row data...', switch2Value: false }]), 
}; 

// ... 

     renderRow={(rowData) => (
      <View style={styles.row}> 
      <Text>{rowData.data}</Text> 
      <Switch 
       value={rowData.switch2Value} 
       onValueChange={value => this.setState({ 
       dataSource: this.state.dataSource.cloneWithRows([{ ...rowData, switch2Value: value }]) 
       })} 
      /> 
      </View> 
     )} 

// ... 
+0

嘿,鏈接不工作了。也許消息內的一個片段會更好,下次:) –

+0

@NicGutierrez,對不起,我已經添加了代碼到我的答案。 – mihai1990

+0

真棒!爲此歡呼! –

1

我試圖用終極版,並切換到重現所描述的問題,但我唯一的問題是,開關是一個保留字,所以我把它改成switchState。如果有人需要的工作示例:

JS /動作/ actionTypes.js

export const TRIGGER_SWITCH = 'TRIGGER_SWITCH'; 

JS /動作/ switchActions。JS

import { TRIGGER_SWITCH } from './actionTypes'; 

export const triggerSwitch = value => ({ 
    type: TRIGGER_SWITCH, 
    currentValue: value 
}); 

JS /減速器/ switchReducer.js

import { TRIGGER_SWITCH } from '../actions/actionTypes'; 

const initialState = { 
    currentValue: false 
}; 

const switchReducer = (state = initialState, action) => { 
    switch(action.type) { 
    case TRIGGER_SWITCH: 
     return { 
     currentValue: action.currentValue 
     }; 
    default: 
     return state; 
    } 
}; 

export default switchReducer; 

JS/store.js

import { 
    createStore, 
    applyMiddleware, 
    combineReducers 
} from 'redux'; 
import { createLogger } from 'redux-logger'; 
import switchReducer from './reducers/switchReducer'; 

const logger = createLogger(); 

export default (initialState = {}) => (
    createStore(
    combineReducers({ 
     switchState: switchReducer 
    }), 
    initialState, 
    applyMiddleware(logger) 
) 
); 

JS /組件/ App.js

import React, { Component } from 'react'; 
import { 
    StyleSheet, 
    View, 
    Switch 
} from 'react-native'; 


export default class App extends Component { 

    constructor(props) { 
    super(props); 

    this._handleSwitch = this._handleSwitch.bind(this); 
    } 

    _handleSwitch(value) { 
    this.props.actions.triggerSwitch(value); 
    } 

    render() { 
    const { switchState } = this.props; 

    return (
     <View style={styles.container}> 
     <Switch 
      onValueChange={this._handleSwitch} 
      value={switchState.currentValue} 
     /> 
     </View> 
    ); 
    } 
} 

const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    justifyContent: 'center', 
    alignItems: 'center', 
    backgroundColor: '#F5FCFF', 
    }, 
}); 

JS /容器/ App.js

import { bindActionCreators } from 'redux'; 
import { connect } from 'react-redux'; 
import { triggerSwitch } from '../actions/switchActions'; 
import App from '../components/App'; 

const mapStateToProps = state => ({ 
    switchState: state.switchState 
}); 

const mapDispatchToProps = dispatch => ({ 
    actions: bindActionCreators({ 
    triggerSwitch 
    }, dispatch) 
}); 

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

index.ios.js

import React, { Component } from 'react'; 
import { AppRegistry } from 'react-native'; 
import { Provider } from 'react-redux'; 
import createStore from './js/store'; 
import App from './js/containers/App'; 

const store = createStore(); 


const SwitchTest =() => (
    <Provider store={store}> 
    <App /> 
    </Provider> 
); 

AppRegistry.registerComponent('SwitchTest',() => SwitchTest); 

export default SwitchTest; 

的package.json依賴

"dependencies": { 
    "react": "16.0.0-alpha.12", 
    "react-native": "0.46.4", 
    "react-redux": "^5.0.5", 
    "redux": "^3.7.2", 
    "redux-logger": "^3.0.6" 
}, 
相關問題