React Native集成Redux-saga时触发Invariant violation错误求助
我帮你排查了代码里的几个关键问题,这些问题导致了你遇到的错误——虽然你还没接入redux-saga,但Redux本身的配置和使用错误已经触发了异常:
问题1:Reducer中Action类型导入错误
你的Initial-reducer.js里导入action类型的方式不对,你直接默认导入了整个action模块,但实际上你需要的是导出的USER_INITIAL_INPUT常量:
错误代码:
import USER_INITIAL_INPUT from './../action/Initial-action'
修复后:
import { USER_INITIAL_INPUT } from './../action/Initial-action'
同时建议在switch语句里使用这个常量而非硬编码字符串,避免拼写错误:
case USER_INITIAL_INPUT:
问题2:Button onPress中错误地直接执行了Action方法
你在InitialDetails.js的Button组件里,直接写了onPress = {this.props.updateUserInitialInput(this.state)},这会导致组件渲染时就立刻调用这个action,而不是点击按钮时才触发,这会引发Redux状态的异常更新,进而触发Invariant violation。
错误代码:
<Button mode="contained" ... onPress = {this.props.updateUserInitialInput(this.state)} >
修复后:
用箭头函数包裹,确保点击时才执行:
<Button mode="contained" ... onPress={() => this.props.updateUserInitialInput(this.state)} >
问题3:状态更新方法的参数拼写错误
在素食选项的TouchableOpacity里,你调用userInitalInput时传的参数是'isVeg',但你的state属性是isVegeterian,这会导致setState时添加一个新的isVeg属性,而不是更新isVegeterian,进而导致状态混乱:
错误代码:
<TouchableOpacity onPress={this.userInitalInput.bind(this,'isVeg',false)} ...> <TouchableOpacity onPress={this.userInitalInput.bind(this,'isVeg',true)} ...>
修复后:
把参数改成'isVegeterian':
<TouchableOpacity onPress={this.userInitalInput.bind(this,'isVegeterian',false)} ...> <TouchableOpacity onPress={this.userInitalInput.bind(this,'isVegeterian',true)} ...>
问题4:mapStateToProps中的alert可能引发异常
你在mapStateToProps里用了alert(JSON.stringify(state)),每次Redux状态变化都会弹出alert,这在React Native中可能会干扰组件渲染流程,建议换成console.log用于调试:
修复后:
function mapStateToProps (state) { console.log('Current state:', JSON.stringify(state)) return{ userInput : state } }
修复后的关键文件示例
Initial-reducer.js
import { USER_INITIAL_INPUT } from './../action/Initial-action' const initialState = { userInitalInputFromUser :{ animal : 'tige' } } const InitialReducer = (state = initialState,action) => { switch(action.type){ case USER_INITIAL_INPUT: return{ ...state, userInitalInputFromUser : action.action } default: return state } } export default InitialReducer
InitialDetails.js(关键修改部分)
// ... 其他代码保持不变 userInitalInput(whichState,value){ whichState ==='cookingSkill' ? this.setState({cookingSkill:value}) : this.setState({[whichState]:value}) } // ... 其他代码保持不变 <TouchableOpacity onPress={this.userInitalInput.bind(this,'isVegeterian',false)} style={ [initialPageCSS.buttons, this.state.isVegeterian ? null : initialPageCSS.acitveButton] } activeOpacity={0.5}> <Image source={require('../../assets/images/avatar.png')} style={initialPageCSS.ImageIconStyle}/> <Text style={initialPageCSS.TextStyle}> Nope, Show me all Recipes </Text> </TouchableOpacity> <TouchableOpacity onPress={this.userInitalInput.bind(this,'isVegeterian',true)} style={ [initialPageCSS.buttons, this.state.isVegeterian ? initialPageCSS.acitveButton : null] } activeOpacity={0.5}> <Image source={require('../../assets/images/avatar.png')} style={initialPageCSS.ImageIconStyle}/> <Text style={initialPageCSS.TextStyle}> Yes, Hide recipes with meat</Text> </TouchableOpacity> <View style = {initialPageCSS.getStartedBtnWrapper}> <Button mode="contained" theme={{ roundness: 5, width: '90%', dark: true, colors: { primary: '#ec4242', accent: "#ffffff", } }} contentStyle = {{height:50}} onPress={() => this.props.updateUserInitialInput(this.state)} > Get Started </Button> </View> // ... 其他代码保持不变 function mapStateToProps (state) { console.log('Current state:', JSON.stringify(state)) return{ userInput : state } }
把这些修复点都改完之后,你的Redux配置应该就能正常工作,不会再触发Invariant violation错误了。
内容的提问来源于stack exchange,提问作者Sivaprakash D

