GVKun编程网logo

带ES6的ReactJS:当我交流两个组件时,this.props不是一个函数(react两种组件)

12

针对带ES6的ReactJS:当我交流两个组件时,this.props不是一个函数和react两种组件这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展es6语法的reactjs的state状

针对带ES6的ReactJS:当我交流两个组件时,this.props不是一个函数react两种组件这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展es6语法的reactjs的state状态和组件间props传递的实践、javascript – Facebook的react.js – 对象不是一个函数、javascript-ReactJS:this.props.data.map不是函数、React + Jest ..选择一个在另一个组件的prop内部的组件等相关知识,希望可以帮助到你。

本文目录一览:

带ES6的ReactJS:当我交流两个组件时,this.props不是一个函数(react两种组件)

带ES6的ReactJS:当我交流两个组件时,this.props不是一个函数(react两种组件)

我正在使用带有ES6的ReactJS,但是在通过props交流child> parent时遇到一些问题。我的方法示例:

class SearchBar extends React.Component {
  handler(e){
    this.props.filterUser(e.target.value);
  }

  render () {
  return <div>
    <input type='text' className='from-control search-bar' placeholder='Search' onChange={this.handler} />
  </div>
  }
}


export default class User extends React.Component {
  constructor(props) {
    super(props);
    this.state = {name: '',age: '',filter: ''};
  }

  filterUser(filterValue){
    this.setState({
      filter: filterValue
    });
  }

  render() {
    return <div>
      <SearchBar filterUser={this.filterUser} />
      <span>Value: {this.state.filter}</span>
    </div>
  }
}

这返回Uncaught TypeError: this.props.filterUser is not a function

任何想法?绑定也许?

[编辑]解决方案(感谢@knowbody和@Felipe Skinner):

我在构造函数中缺少绑定。在SearchBar构造函数中的绑定可以完美地工作。

使用React.createClass()(ES5),它会自动this为您的功能进行绑定。在ES6中,您需要this手动绑定。更多信息https://facebook.github.io/react/docs/reusable-
components.html#es6-classes

es6语法的reactjs的state状态和组件间props传递的实践

es6语法的reactjs的state状态和组件间props传递的实践

PS:开头的一段废话

       想起一个月前还不知道reactjs该如何下手的而今天有点小体会,还是有点小欣慰,不过回望一些走过的坑和开始时的满头浆糊觉得还是有点恐怖的。今天分享一点实践中的小心得给新手朋友们。

reactjs的es6语法形式

       其他的就不必多说,只说说两个点:

  • constructor和super

  • this.functionName=this.functionName.bind(this)

       constructor(props)和super(props)一般是要么不出现,要么同时出现,意义实际上就是继承,这两个东西其实并不是reactjs的,而是es6的,前者就是一个一般意义的构造函数,相当于es5里面的

function FunctionName(props) {
    this.props=props;
}

       super(props)则是继承父类的属性,(意义相当于es5中的 function Son(name){ Parent.call(this, name) }),并在constructor内部正确拿到this,这个this指向此时的子类。如果在操作this之前(比如console.log(this))没有写super(props)则会报错,意思大概是:不能在super()之前写this!

       而有时候看到constructor()和super(),即没有写props好像也没有什么问题,原因自然是没有在constructor内部用到this.props,实际上在constructor内部一般用到的是this.state居多,貌似this.props没怎么写。。。

       this.functionName=this.functionName.bind(this)这个是绑定方法到子类上,使得这个this就是当前的子类(所谓的this指向)。还可以直接将.bind(this)写函数定义的地方,比如在render渲染的元素上 onClick={this.handleClick.bind(this)}.

this.state和this.setState({})以及propsName={stateName}

       state在reactjs组件状态渲染里面的作用不言而喻,被称为状态渲染机,元素节点的各种属性值及其改变实际上基本是由state提供的状态值及其改变完成的。比如元素的文本改变、表单的value值、checked、disabled甚至css样式都可以做到用state来渲染。以下提供一个简例辅助说明:

import React from ''react'';
import ReactDOM from ''react-dom'';
import $ from ''jquery'';
class Comp extends React.Component {
    constructor(){
        super();
        this.handleChange=this.handleChange.bind(this);
        this.handleClick=this.handleClick.bind(this);
        this.state={
            value: "",
            msg: ""
        }
    }
    handleChange(e){
        this.setState({
            value: e.target.value
        })
    }
    handleClick(){
        let {value}=this.state;
        $.ajax({
            ...
            data: {
                value:value
            },
            success:(data)=>{
                this.setState({
                    msg: data
                })
            }
        })
    }
    render(){
        let {value,msg}=this.state; 
        return(
            <div>
                <input type="text" value={value} onChange={this.handleChange} />
                <input type="button" value="提交" onClick={this.handleClick} />
                <span>{msg? msg:"此处加载ajax返回的信息"}</span>
            </div>
        )
    }
}
ReactDOM.render( <Comp />, document.body)

       以上简例在页面上渲染之后是一个按钮、一个输入框和一个信息提示。由于reactjs提倡单向数据流,在value状态初始为空的情况下,如果直接在输入框中输入而不设置value状态(setState),输入信息无法获取。这个渲染过程是:首先页面加载时根据默认的this.state中的三个状态值生成相应的状态,onChange事件不断改变state的value值,此时state接收到了改变并马上重新渲染页面上输入框内的值,即:只要任何动作改变了state值,页面就会重新渲染相应的地方(关于其他reactjs入门案例demo可以参见本人的github)。

props属性以及传递

       注意一下,以上说constructor内如果没有传递props参数,其内部就不能使用this.props。但这并不意味着其他地方比如render内部不能使用。目前只是体会到组件之间传递的props值的初始来源一般都是state值,可能是实践不够的原因 @_@。。。

1.父组件向子组件传值

       这是比较常见的父子组件之间通信的方式。子组件上的属性值可以理解为一个参数,而需要父组件传递一个实际值。传值这种方式一般是复用组件所必需的,因为有可能有多个页面的内容的某一个部分高度相似甚至相同,这时只需要对一个组件传递不同的值就可以实现多次利用。如下例:

假定组件文件都在根目录下:
//子组件Son.js
class Son extends React.Component{
    render(){
        let {title,userValue,pwdValue,handleChange,handleSubmit}=this.props;
        return(
            <div>
                <h3>{title}</h3>
                <input type="text" value={userValue} onChange={(e)=>handleChange("user",e.target.value} />
                <input type="password" value={pwdValue} onChange={(e)=>handleChange("pwd",e.target.value} />
                <input type="button" value="提交" onClick={handleSubmit} />
            </div>
        )
    }
}
//父组件1:Login.js
import Son from ''./Son.js'';
class Login extends React.Component{
    constructor(){
        super();
        this.handleChange=this.handleChange.bind(this);
        this.handleSubmit=this.handleSubmit.bind(this);
        this.state={
            user:{
                value:"",
                error:false
            },
            pwd:{
                value:"",
                error:false
            }
        }
    }
    handleChange(field,val){
        let newState={value:val, error:true};
        switch(field) {
            case "user":
                if (!val.length){
                    newState.error=false
                } else if (val.length>4) {
                    newState.error=false
                }
                this.setState({
                    user:newState
                })
                break;
            case "pwd":
                if (!val.length){
                    newState.error=false;
                } else if (val.length>6) {
                    newState.error=false
                }
                this.setState({
                    pwd:newState
                })
                break;
        }
    }
    handleSubmit() {
        let {user, pwd}=this.state;
        if (!user.error || !pwd.error) {
            alert("请重试!");
            return;
        } else {
            $.ajax({
                ...
                data: {
                    username: user.value,
                    password: pwd.value
                },
                ...
            })
        }
    render(){
        let {user, pwd}=this.state;
        return(
            <Son title="请登录" userValue={user.value} pwdValue={pwd.value} handleChange={this.handleChange} handleSubmit={this.handleSubmit} />
        )
    }
}

       相信各位看得出来,这是个登录页面的雏形,其中仅限原理说明,先不要纠结规范什么的哈。。。一般来说,既然有登录,也就有注册,注册页面基本上也是这个道理。需要说明的是:子组件上的属性值和方法都是this.props的,这里之所以没有写this.handleChange或者this.handleSubmit是因为子组件本身没有这个方法,因此如果此时在子组件上的方法前加上this.xxx就会报错大概说这个方法不是个函数!属性值也相似;同时利用拆包表达式写this.props表示这些属性和方法都是从父组件上继承而来,只要父组件上定义了方法,因此子组件上此时可以不用写constructor()和super()。

2.父组件的父组件子组件传值

       这个场景主要用于组件嵌套比较多的时候。比如,我们发现在子组件Son.js中,有三个输入框分别是用户名、密码,但貌似有点不伦不类,那么我们就完善一点这个表单:

新建组件Form.js
class Form extends React.Component{
    render(){
        let {handleSubmit, userValue, pwdValue, handleChange}=this.props;
        return(
            <form  onSubmit={handleSubmit} method="post" action="/submit">
                <input type="text" name="user" value={userValue} onChange={(e)=>handleChange("user",e.target.value} />
                <input type="password" name="pwd" value={pwdValue} onChange={(e)=>handleChange("pwd",e.target.value} />
                <input type="submit" />
            </form>
        )
    }
}

       有了这个组件之后,关于表单的Son.js组件可以改造成(同样假定所有组件都在根目录下):

//Son.js
import Form from  ''./Form.js'';
class Son extends React.Component{
    render(){
        let {title,userValue,pwdValue,handleChange,handleSubmit}=this.props;
        return(
            <div>
                <h3>{title}</h3>
                <Form 
                    userValue={userValue}
                    pwdValue={pwdValue}
                    handleChange={handleChange}
                    handleSubmit={handleSubmit}
                />
            </div>
        )
    }
}

       也许新手童鞋们不太明白Son.js组件上的属性和方法命名到底是不是一定要和孙子级组件上的一样,因为本人在学这个地方的时候的确纠结过,不过请注意:只要onChange或者onSubmit这类元素上原生方法后指定的一个函数(Form.js),比如onChange={handleChange},那么这个handleChange在传递的时候,上级组件(Son.js)上的handleChange={handleChange}中,左边是上级组件的方法,可以新命名比如footChange。。。而右边则是传递给下级组件的方法handleChange,所以,下级组件Form.js中onChange的右边函数名必须对应之。

       此外,我们还可以根据Son.js做个简单的欢迎页:

//Welcome.js
class Welcome extends React.Component{
    render(){
        return(
            <h1>欢迎您!</h1>
        )
    }
}
//SonWelcome.js
import Welcome from ''./Welcome.js'';
class SonWelcome extends React.Component{
    render(){
        return(
            <div>
                <h3>{this.props.title}</h3>
                <Welcome />
            </div>
        )
    }
}

       当然,SonWelcom.js太过简单了。。。同时title的值依赖于上一级组件传值确定,兄弟们大开脑洞吧。

3.非上下级关系和非兄弟的组件之间如何传值

       相信这个情况是比较少的,不过这是个值得研究的,有一些师兄和大神们肯定知道如何解决。所谓的兄弟组件就是具有共同的父组件或者“爷组件”的多个组件,这种情况和以上差不多,主要把兄弟组件之间需要的共同的值挂载到上级组件即可。而非上下级和非兄弟组件这种情况的应用场景有点类似(注意,仅仅是类似)session或者cookie,比如有多个页面需要根据用户是否登录或者是否是管理员超级用户来对页面进行不同的渲染。
       先说说可以解决的途径吧,首先推荐的是一个js库:PubSubJs,详情可以去了解一下(实际我也没用过。。。)。其次,说说本人的想法吧。正如上所言,假设这个属性或者方法在渲染组件的时候并不涉及安全性问题,那么何不将其设置为cookie或者session呢?哪个组件需要这个值就将其提出来。如下例两个组件:
暂且写如下,先不管自定义flag从何而来,同时,.active的样式是:display:none;

//CompOne.js
class CompOne extends React.Component{
    render(){
        return(
            <div>
                <p className={flag? "":"active"}>这个第一个组件</p>
            </div>
        )
    }
}
//CompTwo.js
class CompTwo extends React.Component{
    render(){
        return(
            <div>
                <p className={flag? "active":""}>这个第二个组件</p>
            </div>
        )
    }
}

       假设以上两个组件并没有关系,且都带有一个共同的自定义属性flag,这两个组件根据flag的意义进行隐藏或展示。此时,可以建一个组件Cookie内部封装一个构造函数HandleCookie,内部封装三个方法setCookie(name, value, time),getCookie(name),clearCookie(name, value, time)。假设,name是cookie名称,value是cookie的值,time参数是参照当前时间的cookie的保存时间长度,设置为1表示一天后过期,设置-1则表示过期失效。

       照此假定,以上两个组件可以直接在渲染页面的时候取到cookie的flag名称对应的值,并根据值渲染页面。比如在项目的某个文件加载完毕(componentDidMount)的时候设置一个cookie:{flag:"1"},CompOne.js:

//CompOne.js
import Cookie from ''./Cookie.js'';
class CompOne extends React.Component{
    render(){
        let flag=Cookie.getCookie("flag");
        return(
            <div>
                <p className={flag? "":"active"}>这个第一个组件</p>
            </div>
        )
    }
}

       照此安排,这个组件CompOne渲染后就会展示,而CompTwo则会隐藏。不过,这种方式明显不是一种规范的方法,仅仅是想法而已,望轻喷!

写在结尾的话

       以上若有不当之处,还请指正一下,给小弟一个改过自新的机会吧。。。如果童鞋还对其他没有写彻底的地方感兴趣,可以参见本人的一个留言本小项目,乃是本国reactjs、webpack配置、nodejs和express入门的最好材料之一,觉得好用就star一下吧,哎,求star真不好意思^_^

javascript – Facebook的react.js – 对象不是一个函数

javascript – Facebook的react.js – 对象不是一个函数

沿着Facebook的 read.js tutorial,我收到这个错误:
Uncaught TypeError: Property 'CommentList' of object [object Object] is not a function

事实上react.js自己的examples page有:

Uncaught TypeError: object is not a function

任何人都能解释正确的用法吗?

我在教程中的进步

导入以下两个javascripts:

http://fb.me/react-0.4.1.js
http://fb.me/JSXTransformer-0.4.1.js

HTML是一行:

<div id="content"></div>

而javascript或更确切地说< script type =“text / jsx”>看起来像这样:

var CommentBox = React.createClass({
    render: function() {
        return (
           <divhttps://www.jb51.cc/tag/Box/" target="_blank">Box">
        <h1>Comments</h1>
        <CommentList />
        <CommentForm />
        </div>
        );
    }
});


React.renderComponent(
    <CommentBox />,document.getElementById('content')
);


var CommentList = React.createClass({
    render: function() {
        return (
        <div>
        <Comment author="Pete Hunt">This is one comment</Comment>
        <Comment author="Jordan Walke">This is *another* comment</Comment>
        </div>
    );
    }
});

解决方法

这里有两个主要问题.

首先,当调用React.renderComponent时,尚未分配CommentList,因此仍未定义.这导致错误,因为CommentBox的渲染函数引用

<CommentList />

哪个jsx编译成

CommentList(null)

当这个exectutes和CommentList未定义时,我们得到一个错误,因为undefined不是一个函数.要解决这个问题,我们需要做的就是在调用React.renderComponent之前移动CommentList声明.

其次,Comment和CommentForm没有在任何地方定义.我们需要删除对它们的引用,或者从教程中引入它们的声明.

作为参考,这里是原始代码的jsfiddle:http://jsfiddle.net/jacktoole1/nHTr4/

如果我们包含Comment的声明,只需删除对CommentForm的引用,这就是修复代码的样子:http://jsfiddle.net/jacktoole1/VP5pa/

javascript-ReactJS:this.props.data.map不是函数

javascript-ReactJS:this.props.data.map不是函数

我正在尝试从.json文件中获取数据,并通过视图显示结果.以下是scoreboard.json文件.

{
"subject":"scoreboard",
"copyright":"copyright 2015",
"data":
   "games":{
     "next_day_date":"2015-07-22",
     "modified_date":"2015-08-04T07:34:50Z",
     "month":"07",
     "year":"2015",
     "game":[
        {
           "game_type":"R",
           "double_header_sw":"N",
           "location":"Some City, State",
        }, 
        {
           "game_type":"R",
           "double_header_sw":"N",
           "location":"Another City, Another State"
        }
     ]
   }

我只想要“数据”字段,而不想要“主题”或“版权”字段,并且能够通过下面的ajax请求来做到这一点.

	getinitialState: function() {
		return {data: []};
	},
	componentDidMount: function() {
		$.ajax({
		  url: this.props.url,
		  dataType: 'json',
		  cache: false,
		  success: function(data) {
		  	console.log(data.data);
		    this.setState({data: data.data});
		  }.bind(this),
		  error: function(xhr, status, err) {
		    console.error(this.props.url, status, err.toString());
		  }.bind(this)
		});
	},

我将状态传递给接收文件,但是当我尝试调用它时,我收到一个TypeError:this.props.data.map不是一个函数

	render: function() {
		var gameDate = this.props.data.map(function(data) {
			return (
				<h1>{data.modified_date} </h1>
			);
		});

我希望最终能够获取scoreboard.json的“数据”字段中的所有信息(即data.games.game []数组). .map函数似乎对此也不起作用.

我如何在.map函数中获取“数据”字段(更具体而言是Modifyed_date)?

编辑:我可以通过调用data.games.modified_date来记录Modifyed_date,但是,当尝试设置数据状态时:this.state.data = data.games.game我收到一个新的警告:数组或迭代器中的每个子代都应有一个独特的“钥匙”道具.检查“ GameDate”的渲染方法

解决方法:

正如azium指出的那样,我的数据是一个对象,而不是我的结果所期望的数组.

为了获得“游戏”字段中的“游戏”数组,我将状态设置为以下内容:

this.setState({data: data.data.games.game});

为了获取其他字段,我只是创建了一个新状态并将其通过一个属性传递,即Modifyed_date:

this.state.date = data.data.games.modified_date

警告:数组或迭代器中的每个子代均应具有唯一的“键”道具.通过在.map方法内添加“ key”属性来解决:

render: function() {
    var gameDate = this.props.data.map(function(data) {
        return (
            <h1 key={data.location} >{data.location} </h1>
        );
    });

React + Jest ..选择一个在另一个组件的prop内部的组件

React + Jest ..选择一个在另一个组件的prop内部的组件

如何解决React + Jest ..选择一个在另一个组件的prop内部的组件?

我正面临一个问题,最好用类似的例子来描述它:

const ParentComponent = () => {

const doSomething =() => {
// code here
}
return (
    <div>
        <Page
          title= ''''
          titleBar={
              <CustomizedButton
                onClick={doSomething}
              />
          }
        >
     </div>
 )
}

我正在使用Jest,我想在单击按钮后进行一些测试。因此,我的问题是在这个示例中如何调用onClick

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

今天关于带ES6的ReactJS:当我交流两个组件时,this.props不是一个函数react两种组件的介绍到此结束,谢谢您的阅读,有关es6语法的reactjs的state状态和组件间props传递的实践、javascript – Facebook的react.js – 对象不是一个函数、javascript-ReactJS:this.props.data.map不是函数、React + Jest ..选择一个在另一个组件的prop内部的组件等更多相关知识的信息可以在本站进行查询。

本文标签: