Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript TypeError this.props.addNode不是函数_Javascript_Reactjs_Redux_React Redux - Fatal编程技术网

Javascript TypeError this.props.addNode不是函数

Javascript TypeError this.props.addNode不是函数,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我在这个组件中调用的任何操作似乎都会产生相同的错误,而我可以在另一个组件中调用相同的操作,并且没有问题。我已经检查了导入、连接/路由器、参数、操作、路由,我想不出这个。特别是addNode操作 以下是组件: import React, { Component } from 'react' import {connect} from 'react-redux'; import {withRouter} from "react-router-dom"; import PropTypes from '

我在这个组件中调用的任何操作似乎都会产生相同的错误,而我可以在另一个组件中调用相同的操作,并且没有问题。我已经检查了导入、连接/路由器、参数、操作、路由,我想不出这个。特别是addNode操作

以下是组件:

import React, { Component } from 'react'
import {connect} from 'react-redux';
import {withRouter} from "react-router-dom";
import PropTypes from 'prop-types';
import "./AddPersonStyles.css";
import TextFieldGroup from "../common/TextFieldGroup";
import {addNode,getNodes} from "../../actions/nodeActions";
import {getTree,test} from "../../actions/treeactions";



class Interests extends Component {


    constructor(props) {
        super(props);
        this.state = {

           name: "",
           parentName: ""

        }
        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
        //this.props.test();
    }

    componentDidMount(){

    }

    onSubmit(e){
        e.preventDefault();

        const data = {
            name: this.state.name   
        }


        console.log(data.name, this.state.parentName );

        this.props.addNode("Books", "Cultural");
    }

    onChange(e) {

            this.setState({[e.target.name]: e.target.value});

    }





    render() {
        const { displayChildren} = this.state; 

        let children; 
        let listItems;

        if(!(this.props.tree2 === "" || undefined)){
            console.log(this.props.tree2.children);
            listItems = this.props.tree2.children.map((node) =>
                <div key = {node.name}>
                    <Interests key = {node.name} tree2 = {node} />
                </div>
            );
            console.log(listItems);
        }
        if(displayChildren){
            children = (
                <div className = "nodeContainer">
                {listItems}
                <form  className ="newChild" onSubmit = {this.onSubmit}>
                        <div className = "row derp"> 
                            <input

                                className = "form-control squish form-control-lg" 
                                placeholder="name"
                                name="name"
                                value = {this.state.name}
                                onChange = {this.onChange}
                                autoComplete = "off"
                            />             



                            <input type = "submit" value= "+" className = "btn btn-info butt"/>
                        </div>
                    </form> 
                </div>
            )
        }else{
            children = (

                    <div></div>     


            )
        }
        let buttonName = "test";
         if(!(this.props.tree2 === "")){
            console.log(this.props.tree2.name);
            buttonName = this.props.tree2.name;
            this.state.parentName = buttonName; 
        }   
        console.log("hello")
        return (
            <div>
                <div className = "d-flex nodeContainer flex-row ml-2 bd-highlight mb-2">

                    <button type = "button" className = "btn btn-info ml-2" onClick ={() => {
                            this.setState(prevState => ({
                                displayChildren: !prevState.displayChildren
                            }))
                        }}>
                        {buttonName}

                    </button> 
                </div>
                <div className = "col nodeStack">
                    {children}

                </div>


            </div>
        )
    }
}

Interests.propTypes = {
    //getNodes: PropTypes.func.isRequired,
    //node: PropTypes.object.isRequired
    //getTree: PropTypes.func.isRequired,
    //tree: PropTypes.object.isRequired,
    //test: PropTypes.func.isRequired 
    //addNode: PropTypes.func
    //errors: PropTypes.object.isRequired
}

const mapStateToProps = state => ({
    //node: state.node
    //tree: state.tree
    //errors: state.errors
})


export default connect(mapStateToProps, {addNode, getNodes, getTree, test})(withRouter(Interests));
作为参考,这里是我的另一个组件,相同的操作可以很好地工作

import React, { Component } from 'react'
import {connect} from 'react-redux';
import {withRouter} from "react-router-dom";
import PropTypes from 'prop-types';
import TextFieldGroup from "../common/TextFieldGroup";
import TextAreaFieldGroup from "../common/TextAreaFieldGroup";
import SelectListGroup from "../common/SelectListGroup";
import {createProfile} from "../../actions/profileActions";
import Interests from "./Interests";
import{getTree,test} from "../../actions/treeactions";
import {addNode} from "../../actions/nodeActions";
import "./AddPersonStyles.css";



class AddPerson extends Component {

    constructor(props) {
        super(props);
        this.state = {

            name: "",
            sex: "",
            age: "",

            city: "",
            state: "",
            interests: "",
            bio: "",
            errors: {}

        }
        this.props.test();
        //this.props.addNode("Books", "Conceptual");
        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
        this.onSelectChange = this.onSelectChange.bind(this);
    }

    componentDidMount(){

    }

    componentWillReceiveProps(nextProps){

        if(nextProps.errors){
            this.setState({errors: nextProps.errors});
        }
    }
    onSubmit(e){
        e.preventDefault();

        const profileData = {
            name: this.state.name,
            sex: this.state.sex,
            age: this.state.age,
            city: this.state.city,
            state: this.state.state, 

            interests: this.state.interests,
            bio: this.state.bio
        }
        //console.log(profileData);
        this.props.createProfile(profileData, this.props.history);
    }

    onChange(e) {

            this.setState({[e.target.name]: e.target.value});

    }

    onSelectChange(e) {
        this.setState({status: e.target.value});
        console.log(this.status);
        console.log("derp");
    }

    render() {
        const {errors} = this.state; 

        const {tree} = this.props; 
        console.log(tree);
        console.log("here2");
        //select options for status
        const options = [

            {
                label: 'male',
                value: "male"
            },

            {label: 'female', value: "female"}
        ];



        return (
            <div className = "add-person">
                <div className = "container">
                    <div className = "row">
                        <div className = "col-md-8 m-auto">
                            <h1 className = "display-4 text-center">Add Person</h1>
                            <p className = "lead text-center">
                                enter info
                            </p>
                            <small className = "d-block pb-3">* = required fields</small>

                            <form  onSubmit = {this.onSubmit}>

                                <TextFieldGroup 
                                    placeholder = "name"
                                    name = "name"
                                    value = {this.state.name}
                                    onChange = {this.onChange}
                                    error = {errors.name}
                                    info = "name"
                                    autoComplete = "off"

                                />
                                <SelectListGroup 
                                    placeholder = "sex"
                                    name = "sex"
                                    value = {this.state.sex}
                                    onChange = {this.onChange}
                                    options = {options}
                                    error = {errors.sex}
                                    info = "sex"
                                />
                                <TextFieldGroup 
                                    placeholder = "age"
                                    name = "age"
                                    value = {this.state.age}
                                    onChange = {this.onChange}
                                    error = {errors.age}
                                    info = "age"
                                />
                                <TextFieldGroup 
                                    placeholder = "city"
                                    name = "city"
                                    value = {this.state.city}
                                    onChange = {this.onChange}
                                    error = {errors.city}
                                    info = "city"
                                />
                                <TextFieldGroup 
                                    placeholder = "state"
                                    name = "state"
                                    value = {this.state.state}
                                    onChange = {this.onChange}
                                    error = {errors.state}
                                    info = "state"
                                />


                                <TextFieldGroup 
                                    placeholder = "interests"
                                    name = "interests"
                                    value = {this.state.interests}
                                    onChange = {this.onChange}
                                    error = {errors.interests}
                                    info = "interests"
                                />

                                <TextAreaFieldGroup 
                                    placeholder = "bio"
                                    name = "bio"
                                    value = {this.state.bio}
                                    onChange = {this.onChange}
                                    error = {errors.bio}
                                    info = "bio"
                                />


                                <input type = "submit" value= "Submit" className = "btn btn-info btn-block mt-4"/>
                            </form>   

                        </div>
                    </div>
                </div>
                <br />
                <div className = "interests">
                    <div className = "row">
                        <div className = "col">
                             <br />

                            <h1 className = "display-4 text-center">Interests</h1>

                            <Interests tree2 = {tree.tree} />
                            {console.log(tree.tree)}
                            <div className = "container">
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        )
    }
}

AddPerson.propTypes = {
    profile: PropTypes.object.isRequired,
    errors: PropTypes.object.isRequired,
    test: PropTypes.func.isRequired,
    tree: PropTypes.object.isRequired
}

const mapStateToProps = state => ({
    profile: state.profile,
    errors: state.errors,
    tree: state.tree
});

export default connect(mapStateToProps, {createProfile, addNode, test})(withRouter(AddPerson));
import React,{Component}来自“React”
从'react redux'导入{connect};
从“react router dom”导入{withRouter};
从“道具类型”导入道具类型;
从“./common/TextFieldGroup”导入TextFieldGroup;
从“./common/TextAreaFieldGroup”导入TextAreaFieldGroup;
从“./common/SelectListGroup”导入SelectListGroup;
从“../../actions/profileActions”导入{createProfile};
从“/利息”导入利息;
从“./../actions/treeactions”导入{getTree,test}”;
从“../../actions/nodeActions”导入{addNode}”;
导入“/AddPersonStyles.css”;
类AddPerson扩展组件{
建造师(道具){
超级(道具);
此.state={
姓名:“,
性别:“,
年龄:“,
城市:“,
州:“,
利益:“,
生物信息:“,
错误:{}
}
this.props.test();
//this.props.addNode(“书籍”、“概念”);
this.onChange=this.onChange.bind(this);
this.onSubmit=this.onSubmit.bind(this);
this.onSelectChange=this.onSelectChange.bind(this);
}
componentDidMount(){
}
组件将接收道具(下一步){
if(nextrops.errors){
this.setState({errors:nextrops.errors});
}
}
提交(e){
e、 预防默认值();
常量配置文件数据={
名称:this.state.name,
性:这个,州,性,
年龄:这个州,
城市:这个州,这个城市,
州:这个州,
利益:这个国家利益,
生物:这个。状态。生物
}
//console.log(profileData);
this.props.createProfile(profileData,this.props.history);
}
onChange(e){
this.setState({[e.target.name]:e.target.value});
}
选举变更(e){
this.setState({status:e.target.value});
console.log(this.status);
控制台日志(“derp”);
}
render(){
const{errors}=this.state;
const{tree}=this.props;
控制台日志(树);
控制台日志(“此处2”);
//选择状态选项
常量选项=[
{
标签:‘男性’,
价值观:“男性”
},
{标签:'female',值:'female'}
];
返回(
添加人

输入信息

*=必填字段

兴趣 {console.log(tree.tree)} ) } } AddPerson.propTypes={ 配置文件:PropTypes.object.isRequired, 错误:PropTypes.object.isRequired, 测试:需要PropTypes.func.isRequired, 树:PropTypes.object.isRequired } 常量mapStateToProps=状态=>({ profile:state.profile, 错误:state.errors, 树:state.tree }); 导出默认连接(mapstatetops,{createProfile,addNode,test})(withRouter(AddPerson));
出现错误是因为您在普通的
组件上调用
props.addNode
props.addNode
仅在要导出的高阶组件中定义。您错误地使用了普通且未连接的组件,该组件上没有
connect
withRouter
绒毛:

...
listItems = this.props.tree2.children.map((node) =>
  <div key = {node.name}>
    <Interests key = {node.name} tree2 = {node} />
  </div>
);
...
。。。
listItems=this.props.tree2.children.map((节点)=>
);
...
当你使用绒毛时,一切都会好起来:

...
const InterestsWithFluff = connect(...)(withRouter(Interests))
listItems = this.props.tree2.children.map((node) =>
  <div key = {node.name}>
    <InterestsWithFluff key = {node.name} tree2 = {node} />
  </div>
);
...
。。。
const InterestsWithFluff=连接(…)(带路由器(兴趣))
listItems=this.props.tree2.children.map((节点)=>
);
...

更新。我认为,由于组件是嵌套的并且是递归的,就像在树层次结构中一样,因此它会导致redux和mapstatetoprops出现问题。已经找到了修复itupdate 2的确切方法。我更相信这就是问题所在。我理解将组件分为表示组件和容器组件的概念。显然,您正在呈现
组件,而无需连接它们并添加路由器。递归嵌套组件不是问题,但是,错误地嵌套组件是问题。在呈现子组件时,您可以只传递
{…this.props}
。然而,从架构的角度来看,我认为您应该使用两个组件——一个是连接的,另一个是仅获取道具。连接的不应该是递归的。实际上
{…this.props}key={node.name}tree2={node}
可能就足够了
...
const InterestsWithFluff = connect(...)(withRouter(Interests))
listItems = this.props.tree2.children.map((node) =>
  <div key = {node.name}>
    <InterestsWithFluff key = {node.name} tree2 = {node} />
  </div>
);
...