【问题标题】:Invariant Violation: Element type is invalid using react-redux不变违规:使用 react-redux 的元素类型无效
【发布时间】:2018-07-19 01:12:53
【问题描述】:

对不起我的问题。我搜索了很多这样的问题,但其中任何一个都不是我的解决方案。

我是 React-native 的新手。我在我的项目中使用了 2 个组件,并且在这两个组件中我都使用了 redux connect() 函数。 connect() 在Main.js 中工作正常。但在Todos.js 中出现错误。我尝试了很多解决方案,比如不同类型的导入/导出,但还没有工作。

Invariant Violation:元素类型无效:应为字符串(对于 内置组件)或类/函数(用于复合组件) 但得到:未定义。您可能忘记从 定义它的文件,或者您可能混淆了默认值和命名 进口。

检查Main的渲染方法。

Main.js

import React, { Component } from 'react';
import { StyleSheet, Text, View, StatusBar, TextInput, ScrollView, TochableOpacity } from 'react-native';
import {Provider} from 'react-redux';
import {Todos} from './Todos';
import {connect} from 'react-redux';
import {addTodo} from '../actions';


class Main extends Component {
    constructor(props) {
        super(props);
        this.addNewTodo = this.addNewTodo.bind(this); // Here is the key
        this.state = {
            newTodoText: ""
        };
    }

    addNewTodo(){
        var {newTodoText} = this.state;
        console.log(newTodoText);
        if (newTodoText && newTodoText != "") {
            this.setState({
                newTodoText: ""
            })
            this.props.dispatch(addTodo(newTodoText));
        }
    }
    render() {
        var renderTodos = () => {
            if (this.props.todos) {
                return this.props.todos.map((todo) => {
                    return (
                        <Todos text={todo.text} key={todo.id} id={todo.id}/>
                    );
                });
            }
        }
        return (

            <View style={styles.container}>
                <StatusBar barStyle="light-content"></StatusBar>
                <View style={styles.topBar}>
                    <Text style={styles.title}>
                        ToDo List
                    </Text>
                </View>
                <View style={styles.inputContainer}>
                    <TextInput
                        onChangeText={(text) => this.setState({newTodoText:text})}
                        value={this.state.newTodoText}
                        returnKeyType="done"
                        placeholder="New ToDo"
                        onSubmitEditing={this.addNewTodo}
                        underlineColorAndroid="transparent"
                        style={styles.input}
                        >

                    </TextInput>
                </View>
                <ScrollView automaticallyAdjustContentInsets={false}>
                    {renderTodos()}
                </ScrollView>
            </View>
        );
    }
}


...

var mapStateToProps = (state) => {
    return {
        todos: state.todos
    };
}
export default connect (mapStateToProps)(Main);

ToDos.js

import React, { Component } from 'react';
import { StyleSheet, Text, View, StatusBar, TextInput, ScrollView,TochableOpacity } from 'react-native';
import {Provider} from 'react-redux';
import {connect} from 'react-redux';
import {deleteTodo} from '../actions';

class Todos extends Component {
    deleteSelf() {
        this.props.dispatch(deleteTodo(this.props.id))
    }

    render(){
        return (
            <TochableOpacity onPress={this.deleteSelf} >
                <View style={styles.todoContainer}>
                    <Text style={styles.todoText}>
                        {this.props.text}
                    </Text>
                </View>
            </TochableOpacity>
        );
    }
};

export default connect()(Todos);

注意

虽然我没有添加redux connect,但我没有任何问题。

【问题讨论】:

  • 如果this.props.todos 是假的,那么函数renderTodos 将返回未定义。您需要显式返回nullfalse,或者在您的jsx 中写入条件{this.props.todos &amp;&amp; renderTodos}

标签: javascript react-native react-redux


【解决方案1】:

一切似乎都很好,除了 renderTodos 我不确定什么是确切的问题,但您可以尝试关注。在render函数外定义renderTodo,条件不满足时返回null。

import React, { Component } from 'react';
import { StyleSheet, Text, View, StatusBar, TextInput, ScrollViewTochableOpacity } from 'react-native';
import { Provider } from 'react-redux';
import { Todos } from './Todos';
import { connect } from 'react-redux';
import { addTodo } from '../actions';


class Main extends Component {
    constructor(props) {
        super(props);
        this.addNewTodo = this.addNewTodo.bind(this); // Here is the key
        this.renderTodos = this.renderTodos.bind(this);
        this.state = {
            newTodoText: ""
        };
    }


    addNewTodo() {
        var { newTodoText } = this.state;
        console.log(newTodoText);
        if (newTodoText && newTodoText != "") {
            this.setState({
                newTodoText: ""
            })
            this.props.dispatch(addTodo(newTodoText));
        }
    }
    /**
     * Define renderTodo outside in outside of render function
    */
    renderTodos() {
        if (this.props.todos) {
            return this.props.todos.map((todo) => {
                return (
                    <Todos text={todo.text} key={todo.id} id={todo.id} />
                );
            });
        }

        /**
         * return null when condition will not meet
         */
        return null;
    }
    render() {
        return (

            <View style={styles.container}>
                <StatusBar barStyle="light-content"></StatusBar>
                <View style={styles.topBar}>
                    <Text style={styles.title}>
                        ToDo List
                    </Text>
                </View>
                <View style={styles.inputContainer}>
                    <TextInput
                        onChangeText={(text) => this.setState({ newTodoText: text })}
                        value={this.state.newTodoText}
                        returnKeyType="done"
                        placeholder="New ToDo"
                        onSubmitEditing={this.addNewTodo}
                        underlineColorAndroid="transparent"
                        style={styles.input}
                    >

                    </TextInput>
                </View>
                <ScrollView automaticallyAdjustContentInsets={false}>
                    {/*Add this as now renderTodos is bind to constructor class*/}
                    {this.renderTodos()}
                </ScrollView>
            </View>
        );
    }
}




var mapStateToProps = (state) => {
    return {
        todos: state.todos
    };
}
export default connect(mapStateToProps)(Main);

【讨论】:

    猜你喜欢
    • 2019-12-28
    • 2019-06-07
    • 1970-01-01
    • 2019-10-24
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    相关资源
    最近更新 更多