2017-02-04 23:20:43 Sophie_U 阅读数 1862
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57468 人正在学习 去看看 李宁

一、React组件是状态机

1.1 状态理解
React的数据流:数据由父节点向下传递到子节点(由外到内传递),如果顶层组件某个prop改变,React会向下传递,重新渲染所有使用过该属性的组件。

react组件是一个状态机,组件都有一个初始状态,通过与用户的交互,使状态发生改变,然后重新渲染UI,让用户界面与数据保持一致。
在传统js中,如果数据发生了变化,我们需要操作都DOM来重新设置渲染UI,而react中只需要根据state,然后根据新的state重新渲染用户界面。

1.2 state和prop都是设置数据,它们有什么区别?

1、this.props属性:由父节点传入到组件内部,只读,不可修改。组件动态传入参数的关键。
组件默认值是一个对象,会在组件使用时,把外部的传参“合并”到props属性中
2、this.state 状态:由组件自己创建,可以修改,一般由用户交互产生新的状态(数据)。
总结props和state的区别:它们都可以用来存放数据,但props不可修改(只是设置属性),state可修改(用于用户交互)

1.3 交互实例

对react组件的this.state使用大概三步:
1、创建组件 React.createClass()
2、初始化状态: getInitialState
3、根据状态渲染数据
4、设计交互改变state的逻辑:this.setState

    <script type="text/babel">
        var Inte=React.createClass({
            doClick:function(){
                if(this.state.stateNow==='on'){
                    this.setState({
                        stateNow:'off'
                    })
                }else{
                    this.setState({
                        stateNow:'on'
                    })
                }
            },
            getInitialState:function(){
                return {
                    stateNow:'off'
                }
            },
            render:function(){
                return (
                    <div>
                        <p>现在的状态是:{this.state.stateNow==='on'?'已开启':'已关闭'}</p>
                        <button onClick={this.doClick}>点我改变状态</button>
                    </div>
                )

            }
        });
        ReactDOM.render(
            <Inte />,
            document.querySelector('#box')
        )
    </script>

如上:

1、通过{this.state.stateNow===’on’?’已开启’:’已关闭’}来渲染数据
2、通过绑定点击事件doClick来根据用户点击改变state。通过this.setState来改变状态值。

2019-03-24 15:27:50 qq_40190624 阅读数 1501
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57468 人正在学习 去看看 李宁

需求: 一个标签,随着多条数据动态生成多条标签元素

当前父组件引入了子组件;

父组件:

import React, { Component } from 'react';
import './App.css';
import Footer from './components/layout/Footer';
class App extends Component {
  state = {
    persons: [
      {
        name: "周家大小姐",
      }, {
        name: "陈家大小姐",
      }, {
        name: "王家大小姐",
      }
    ],
    showPreson: false,

  };
  // 显示隐藏
  click = () => {
    const doesShow = this.state.showPreson;
    this.setState({
      showPreson: !doesShow
    })
  }
  render() {
    //定义一个空值,在else的时候使用
    let persons = null;
    if (this.state.showPreson) {
      persons = (
        <div>
          {
            this.state.persons.map((person) => {
              return (
                // 对map 循环出来的每个属性插入标签元素
                <Footer name={person.name} v-if="showPreson" key={person.name} />
              )
            })
          }
        </div>
      )
    }
    return (
      <div className="App">
        <button onClick={this.click}>显示与隐藏</button>
        {/* 当showPreson为falser 的时候走这一步为空也就是隐藏 */}
        {persons}
      </div>
    );
  }
}

export default App;

子组件:

import React from 'react'
import './Footer.css'

const person = (props) =>{
  return(
    <div className="footer">
        <p>我的名字叫{props.name}</p>
    </div>
  )
}
export default person;


 

2019-11-26 16:34:40 qq_35713752 阅读数 36
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57468 人正在学习 去看看 李宁

通常你需要在一个组件中渲染列表。或者循环遍历渲染相同的多个组件,下面看看怎么实现:

先来个有 If 判断的字组件循环渲染:

    
  render() {
    // 聊天列表组件
    function MsgList(props){
      const list = props.list;
        const listItems = list.map((item,idx) =>{
            if(item.messageSpecificType==1||item.messageSpecificType==6){
                return (
                  <div key={idx} className={styles.itemTxt}>
                       <div className={styles.name}>{item.nickName}:</div>
                       <div className={styles.msg}>{item.content}</div>
                       <div className={styles.time}> {item.sendTime}</div>
                   </div>
                )
            }else if(item.messageSpecificType==2){
                  return (
                    <div key={idx} className={styles.itemTxt}>
                         <div className={styles.name}>{item.nickName}:</div>
                         <img  className={styles.img} src={item.imageUrl} />
                         <div className={styles.time}> {item.sendTime}</div>
                     </div>
                  )
            }
        })
      return (
        <span>{listItems}</span>
      );
    }
    return(
      <span> {this.state.list ? (<MsgList  list={this.state.list}/>):null}  </span>
    )
  }

再来看一下没有 if 判断的,更简单了

我们可以把需要重复渲染的组件重构成一个组件,这个组件接收一个数组作为参数并输出一个元素列表。

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

当我们运行这段代码,将会看到一个警告 a key should be provided for list items,意思是当你创建一个元素时,必须包括一个特殊的 key 属性。

让我们来给每个列表元素分配一个 key 属性来解决上面的那个警告:

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
2016-06-03 20:24:24 mqy1023 阅读数 3749
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57468 人正在学习 去看看 李宁

组件可以包含属性和状态。

  • 属性(props):类似 HTML 中的属性,在绘制的时候可以直接在标签中添加属性,然后在组件中通过 this.props.属性名 获取。props属性是父组件控制子组件的单向数据流传输的关键;

  • 状态(state):维护组件内部的状态。一个组件就是一个状态机。React 把用户界面当作简单状态机,把用户界面想像成拥有不同状态然后渲染这些状态。在 React 中,一旦组件的 state 发生变化,用户界面有改动的部分就会被重绘。组件的状态通常在组件的内部函数 getInitialState() 中声明,使用 setState() 函数更新值,并通过 this.state.状态名 来获取值。state状态只属于组件自身,组件运行时自身需修改的数据就是状态


一、props

  父组件想要和子组件通信就要通过props,子组件通过this.props.xxx获取父组件传递给子组件的值

var Parent = React.createClass({  
    getInitialState: function(){
        return{
            data: 'parent'
        }
    },
    render: function(){
        return <div><Children fromParent={this.state.data}/></div>;
    }
})
var Children = React.createClass({  
    render: function(){
        return <div>{this.props.fromParent}</div>;
    }
})

  父组件通过在标签内fromParent={this.state.data}定义想要传给子组件的属性、当然属性的类型也是各种各样,包括函数。
  子组件通过this.props.fromParent获取值。
  【注意】 React强烈不推荐去修改自身的props,因为这会破坏UI和Model的一致性,props只能够由使用者来决定,props只会根据父组件传递的值改变而改变,修改props并不会影响父组件的值。

var HelloWorld = React.createClass({
   render: function () { 
        return <p>Hello, {this.props.name1 + ' ' + this.props.name2}</p>;
    },
});
var HelloUniverse = React.createClass({
    getDefaultProps: function () {
        return {
            name1: 'Tim',
            name2: 'John',
        };
    },
    render: function () {
        return <div>
          <HelloWorld {...this.props}></HelloWorld> //...props获取属性对象
         </div>
    },
});
ReactDOM.render(<div><HelloUniverse></HelloUniverse></div>, document.body);

可以通过props属性传递函数

var ChildComponent = React.createClass({
  render: function() {
    return (
      <div>
        <div className="prompt">当点击button时,父组件的performMagic函数将被调用</div>
        {/* Props属性可以是任何有效的jacascript表达式,包括函数
         */}
        <button onClick={this.props.onMagicClick}>Do Magic</button>
      </div>
    );
  }
});

var ParentComponent = React.createClass({
  performMagic: function() {
    alert('perform parent function!');
  },

  render: function() {
    return (
      <div>
        {/* 【注意】如何将函数作为prop属性传递给子组件 */}
        <ChildComponent onMagicClick={this.performMagic} />
      </div>
    );
  }
});

ReactDOM.render(
  <ParentComponent />,
  document.getElementById('container')
);

二、PropTypes(Props 验证)

  组件的属性可以接受任意值,字符串、对象、函数等等都可以。有时,我们需要一种机制,验证别人使用组件时,提供的参数是否符合要求。
  组件类的PropTypes属性,就是用来验证组件实例的属性是否符合要求
属性类型有:string、number、object、func、array、bool …

var MyTitle = React.createClass({
  propTypes: {
    title: React.PropTypes.string.isRequired,
  },

  render: function() {
     return <h1> {this.props.title} </h1>;
   }
});

  上面的Mytitle组件有一个title属性。PropTypes 告诉 React,这个 title 属性是必须的,而且它的值必须是字符串。现在,我们设置 title 属性的值是一个数值。

var data = 123;
ReactDOM.render(
  <MyTitle title={data} />,
  document.body
);

这样一来,title属性就通不过验证了。控制台会显示一行错误信息。

Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.


三、getDefaultProps

getDefaultProps方法可以用来设置组件属性的默认值。不过,这应该只针对那些非必需属性。

var MyTitle = React.createClass({
  getDefaultProps : function () {
    return {
      title : 'Hello World'
    };
  },

  render: function() {
     return <h1> {this.props.title} </h1>;
   }
});

ReactDOM.render(
  <MyTitle />,
  document.body
);

上面代码会输出”Hello World”。

四、子节点this.props.children

  this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点

var NotesList = React.createClass({
  render: function() {
    return (
      <ol>
      {
        React.Children.map(this.props.children, function (child) {
          return <li>{child}</li>;
        })
      }
      </ol>
    );
  }
});

ReactDOM.render(
  <NotesList>
    <span>hello</span>
    <span>world</span>
  </NotesList>,
  document.body
);

上面代码的 NoteList 组件有两个 span 子节点,它们都可以通过 this.props.children 读取,运行结果如下:

【注意】 this.props.children 的值有三种可能:如果当前组件没有子节点,它就是 undefined ;如果有一个子节点,数据类型是 object ;如果有多个子节点,数据类型就是 array 。所以,处理 this.props.children 的时候要小心。
  React 提供一个工具方法 React.Children 来处理 this.props.children 。我们可以用 React.Children.map 来遍历子节点,而不用担心 this.props.children 的数据类型是 undefined 还是 object


一、State状态

  state让组件动态化;组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI
【注意】React自动bind绑定方法到组件实例,不需要this.handleClick.bind(this).

var LikeButton = React.createClass({
  getInitialState: function() {
    return {liked: false};
  },
  handleClick: function(event) {
    //传入key-value键值对的{}对象给setState改变state
    this.setState({liked: !this.state.liked});//state改变后render重新渲染
  },
  render: function() {
    var text = this.state.liked ? 'like' : 'haven\'t liked';
    return (
      <p onClick={this.handleClick}>
        You {text} this. Click to toggle.
      </p>
    );
  }
});

ReactDOM.render(
  <LikeButton />,
  document.getElementById('example')
);

  上面代码是一个 LikeButton 组件,它的 getInitialState 方法用于定义初始状态,也就是一个对象,里面包含你想要定义的初始状态;这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。
  由于 this.propsthis.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性

  不建议在 getDefaultProps、getInitialState、shouldComponentUpdate、componentWillUpdate、render 和 componentWillUnmount 中调用 setState,【特别注意】:不能在 shouldComponentUpdate 和 componentWillUpdate中调用 setState,会导致循环调用。

//综合小例子
var Board = React.createClass({
  render: function() {
    var className = "board";
    if (this.props.selected) {
      className += " selected";
    }
    return (
      <div className={className}>
        {this.props.index + 1}
      </div>
    );
  }
});

var BoardSwitcher = React.createClass({
  render: function() {
    var boards = [];
    for (var ii = 0; ii < this.props.numBoards; ii++) {
      var isSelected = ii === 0;
      boards.push(
        <Board index={ii} selected={isSelected} key={ii} />
      );
    }
    return (
      <div>
        <div className="boards">{boards}</div>
        <button>Toggle</button>
      </div>
    );
  }
});

ReactDOM.render(
  <BoardSwitcher numBoards={3} />,
  document.getElementById('container')
);

  


一、获取真实的DOM节点

  组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。
但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性

var MyComponent = React.createClass({
  handleClick: function() {
    this.refs.myTextInput.focus();
  },
  render: function() {
    return (
      <div>
        <input type="text" ref="myTextInput" />
        <input type="button" value="Focus the text input" onClick={this.handleClick} />
      </div>
    );
  }
});

ReactDOM.render(
  <MyComponent />,
  document.getElementById('example')
);

  上面代码中,组件 MyComponent 的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点
  【注意】由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。
  React 组件支持很多事件,除了 Click 事件以外,还有 KeyDownCopyScroll

二、表单

  用户在表单填入的内容,属于用户跟组件的互动,所以不能用 this.props 读取

var Input = React.createClass({
  getInitialState: function() {
    return {value: 'Hello!'};
  },
  handleChange: function(event) {
    this.setState({value: event.target.value});
  },
  render: function () {
    var value = this.state.value;
    return (
      <div>
        <input type="text" value={value} onChange={this.handleChange} />
        <p>{value}</p>
      </div>
    );
  }
});
ReactDOM.render(<Input/>, document.body);

  上面代码中,文本输入框的值,不能用 this.props.value 读取,而要定义一个 onChange 事件的回调函数,通过event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况

参考链接
1、《浅入React。 一次》:http://www.wengwang.me/2015/12/02/qian-ru-react-ci-2/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
2、《React入门实例》:http://www.ruanyifeng.com/blog/2015/03/react.html

2018-07-06 18:59:10 YU_M_K 阅读数 304
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57468 人正在学习 去看看 李宁

1:安装react官方脚手架

注意:需要在计算机上安装Node> = 6和npm> = 5.2

npx create-react-app my-app

cd my-app

npm start

2:调整目录结构

3:index.js(程序入口文件)

import React from 'react';
import ReactDOM from 'react-dom';

import TodoList from './TodoList';


ReactDOM.render(<TodoList />, document.getElementById('root'));

4:TodoList.js

import React, { Component ,Fragment} from 'react';

import TodoItem from './TodoItem';


class TodoList extends Component {
  constructor(props){
    super(props);
    this.state={
      inputValue:'',
      list:[],
    }
  }
  render() {
    return (
        <Fragment>{/*一个占位符,只是为了包裹*/}
            <div>
              <input
                value={this.state.inputValue}
                onChange={this.handleInputChange}//this指的是TodoList
              />
              <button onClick={this.handleBtnClick}>保存</button>
            </div>
            <ul>
                {this.getToDdoItem()}{/*函数加上括号,直接调用*/}
            </ul>
        </Fragment>

    );
  }
  //用map循环遍历list
  getToDdoItem=()=>{
    return this.state.list.map((item,index)=>{
        return (
            <TodoItem
                key={item}
                content={item}
                index={index}//传递给子组件的属性
                deleteItem={this.handleItemDelete}//传递给字组件的函数,
            />
        )
    })
  };
  //使用箭头函数不用再bind(this)
  handleInputChange=(e)=>{
    //旧的setState写法
    // this.setState({
    //     inputValue: e.target.value
    //     // 获取输入框里面的值
    // });

    // 新的setState写法1
    const value=e.target.value;// 获取输入框里面的值
    this.setState(()=>({
            inputValue:value
        }
    ))


  };
  // 点击提交按钮,在原来的数组基础上,添加输入框里的值
  handleBtnClick=()=>{
    //旧的setState写法
    this.setState({
        list:[...this.state.list,this.state.inputValue],
        inputValue:"",
    })
  };
  //点击之后根据索引删除
  handleItemDelete=(index)=>{
      // 新的setState写法2
      this.setState((prevState)=>{//prevState=this.state
          const list=[...prevState.list];
          list.splice(index,1);
          return {
            list,list
          }
      })

  }
}


export default TodoList;

5:TodoItem.js

import   React,{Component} from   'react';


class TodoItem extends Component{

    render(){
        const {content}=this.props;//解构出父组件传来的属性
        return(
            <div onClick={this.handleClick}>
                {content}
            </div>
        )
    }
    //这个函数利用父组件的删除方法
    handleClick=()=>{
        const {deleteItem ,index}=this.props;
        deleteItem(index);//调用父组件传来的属性和函数进行点击删除
    }
}
export default TodoItem;

6:效果图





没有更多推荐了,返回首页