React学习笔记——官网核心概念学习总结

React官方文档学习笔记

React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。

单文件引入使用模板:

  • script引入:
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Title</title>
		<!-- 加载 React。-->
		<!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"。-->
		<!-- 三者的引入顺序会影响 -->
		<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
		<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
		<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
	</head>
	<body>
		<div id="root"></div>
	</body>
	
</html>
	<!--<script type="text/javascript"> -->
	<!-- 快速使用babel转换jsx的混合复杂语法 -->
	<script type="text/babel">
        let ele = <h1>hello,world</h1>
	    ReactDOM.render(ele,document.getElementById("root"))
	</script>

JSX

看起来很像 XML 的 JavaScript 语法扩展。

Vue和React区别

  • vue是html里面嵌入js的一些语法,l通过{{}}等方式简单的使用
  • react是将html放在js当中作为变量模板化使用,使得html也作为变量方式拥有了更多的js的特性。

语法

  1. 在 {} 大括号里面放置任何有效的js代码,语法、函数调用。。。

  2. jsx也可以是表达式

    function getGreeting(user) {
    	if (user) {
    		return <h1>Hello, {formatName(user)}!</h1>;
    	}
    	return <h1>Hello, Stranger.</h1>;
    }
    
  3. ​ JSX 特定属性

    //你可以通过使用引号,来将属性值指定为字符串字面量:
    	const element = <div tabIndex="0"></div>;
    //也可以使用大括号{},来在属性值中插入一个 JavaScript 表达式:
    	const element = <img src={user.avatarUrl}></img>;
    
  4. 因为 JSX 语法上更接近 JavaScript 而不是 HTML

    所以 React DOM 使用 camelCase(小驼峰命名)来定义属性的名称

    class 变成了 className,而 tabindex 则变为 tabIndex。(class是关键字了避免冲突)

  5. 假如一个标签里面没有内容,你可以使用 /> 来闭合标签,就像 XML 语法一样:

    const element = <img src={user.avatarUrl} />;
    
  6. JSX 标签里能够包含很多子元素,只能有一个根元素:

    		const element = (
    			  <div>
    			    <h1>Hello!</h1>
    			    <h2>Good to see you here.</h2>
    			  </div>
    			);
    
  7. 防止xss注入攻击-----会在内部进行以此转义

  8. jsx表示对象:
    Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。
    以下两种示例代码完全等效:

    	const element = (
    			<h1 className="greeting">Hello, world! </h1>
    	);
    	//相当于:
    	const element = React.createElement(
    		'h1',
    		{className: 'greeting'},
    		'Hello, world!'
    	);
    

    React.createElement() 会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象:

    // 注意:这是简化过的结构
    	const element = {
    	    type: 'h1',
    		props: {
    			className: 'greeting',
    			children: 'Hello, world!'
    		 }
    	};
    

    这些对象被称为 “React 元素”。它们描述了你 -->希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建 DOM 以及保持随时更新。

    **注:*在单文件当中使用jsx语法,有时快捷键做注释,在分行的代码中会有html和js注释上的冲突,可以{/ … */}来将他们都作为js代码进行注释

JSX元素渲染

<script type="text/babel">
// React 元素是不可变对象。一旦被创建,你就无法更改它的子元素或者属性。一个元素就像电影的单帧:它代表了某个特定时刻的 UI。
// React 只更新它需要更新的部分
	function tick() {
		let element = (
			<div>
				<h1>hello! EveryBody!</h1>
				<h1>It is {new Date().toLocaleTimeString()}!</h1>
			</div>
		)
		ReactDOM.render(element, document.getElementById('root'));
	}
	setInterval(tick,1000)
</script>

组件和props

  • 函数组件和Class组件

    从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。

    组件名必须大写字母开头

    // 1、函数组件,props是形参,随意取,
    function WelCome (props){
    	return <h1>{props.name},Welcome to there!</h1>;
    }
    //2、class组件,只能写成props,thia.props来自react.Component
    class Hello extends React.Component{
    	render(){
    		return <h1> Hello! {this.props.name}</h1>;
    	}
    }
    
  • 渲染组件

    当 React它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。

    const ele = <WelCome name="zxc"/>
    ReactDOM.render(ele,document.getElementById("root"))
    
  • 组合组件(自下而上)

    function App(){
    	return(
    		<div>
    			<WelCome name="zxc"/>
    			<Hello name="zxc"/>
    		</div>
    	)
    }
    

    注:学会拆分组件(自上而下),及属性prop嵌套的区分

  • Props 的只读性:所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。

State和生命周期

State 与 props 类似,但是 state 是私有的,并且完全受控于当前组件。prop是外部传入的

注:将函数组件转换成 class 组件,只有Class组件能够接受state

class Clock extends React.Component {
    //class 构造函数,在该函数中为 this.state 赋初值:
		constructor(props) {
            //Class 组件应该始终使用 props 参数(传给父类)来调用父类的构造函数。
			super(props);
            //状态变量,相当于vue中的data
			this.state = { date: new Date() };
		}
    //生命周期方法
	//componentDidMount() 方法会在组件已经被渲染到 DOM 中后运行
     	componentDidMount() {
    		this.timerID = setInterval(() => this.tick(),1000);
  		}

  		componentWillUnmount() {
   			 clearInterval(this.timerID); //清除计时器:
  		}

  		tick() {
            //this.setState() 来时刻更新组件 state:
    		this.setState({
      			date: new Date()
    		});
  		}
		render() {
			return ( //将函数组件内容通过return方式在这里使用
				<div>
					<h1>Hello, world!</h1>
                  {/*this.props 和 this.state 是 React 本身设置的,且都拥有特殊的含义*/}
					<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
				</div>
			);
		}
	}

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

State使用注意:

1、State不要直接修改,用this.setState({})来修改

构造函数是唯一可以给this.state初始赋值的地方,

2、state可能是异步的

出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。

因为 this.propsthis.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。

eg:

this.setState({
  counter: this.state.counter + this.props.increment,
});

要解决这个问题,可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

3、State的更新合并

class Clock extends React.Component {
		constructor(props) {
            super(props);
    		this.state = {
      			posts: [],
      			comments: []
   		 };
       
		}
    //setState() 来单独地更新它们:
    //这里的合并是浅合并,所以 this.setState({comments}) 完整保留了 this.state.posts, 但是完全替换了 this.state.comments。
   componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts
      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments
      });
    });
  }
}
	

4、State数据向下传递的,

class Hello extends React.Component{
	render(){
		return (
		//组件可以选择把它的 state 作为 props 向下传递到它的子组件中:
			<FormattedDate date={this.state.date} />
		)
	}
}

//FormattedDate 组件会在其 props 中接收参数 date,但是组件本身无法知道它是来自于 Clock 的 state,或是 Clock 的 props,还是手动输入的:
function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}

5、每个组件都是真正独立的

function App() {
  return (
    <div>
    {/* Clock组件都是同一个组件构造出来的,但是他们有彼此式独立的(可以有独立的props等*/}
      <Clock />
      <Clock />
      <Clock />
    </div>
  );
}

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

React的常用生命周期图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wU0K2OgZ-1641218373735)(C:\Users\zhangxingcai\AppData\Roaming\Typora\typora-user-images\image-20220102155911113.png)]

事件处理

  • **命名:**小驼峰

  • 写法:

    传统的 HTML:

    <button onclick="activateLasers()">
      Activate Lasers
    </button>
    

    在 React 中略微不同:

    <button onClick={activateLasers}>  Activate Lasers
    </button>
    

在 React 中另一个不同点是你不能通过返回 false 的方式阻止默认行为。你必须显式的使用 preventDefault

<a href="#" οnclick="console.log('The link was clicked.'); return false">
  Click me
</a>

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}
  • 使用:
<script type="text/babel">
	class Toggle extends React.Component {
	  constructor(props) {
	    super(props);
	    this.state = {isToggleOn: true};
		console.log(1,this) //this指向组件实例
	    // 为了在回调中使用 `this`,重新绑定为这个Toggle组件实例
	    // this.handleClick = this.handleClick.bind(this);
	  }
	  handleC = ()=>{
			console.log(11)
		}
	  handleClick() {
		console.log(this)  //undefined,这里的handleClick是通过
	    this.setState(state => ({
	      isToggleOn: !state.isToggleOn
	    }));
	  }
	
	  render() {
	    return (
		//handleClick在代码中是作为onClick的回调,所以不是通过实例调用的,是直接调用的
		//类中的方法默认开启了局部的严格模式,因此handleClick中的this为undefined
	    //方法传参
           <div>
     			<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> 
      			<button onClick={this.handleClick.bind(this)}>
	       			{this.state.isToggleOn ? 'ON' : 'OFF'}
	      		</button> 
           </div> 
	    );
	  }
	}
	
	ReactDOM.render(
	  <Toggle />,
	  document.getElementById('root')
	);
</script>

条件渲染

  • if或者条件运算符

    function UserGreeting(props) {
      return <h1>Welcome back!</h1>;
    }
    
    function GuestGreeting(props) {
      return <h1>Please sign up.</h1>;
    }
    //根据isLoggedIn条件渲染
    function Greeting(props) {
      const isLoggedIn = props.isLoggedIn;
      if (isLoggedIn) {
        return <UserGreeting />;
      }
      return <GuestGreeting />;
    }
    
    ReactDOM.render(
      // Try changing to isLoggedIn={true}:
      <Greeting isLoggedIn={false} />,
      document.getElementById('root')
    );
    
  • 元素变量

    function LoginButton(props) {
      return (
        <button onClick={props.onClick}>
          Login
        </button>
      );
    }
    
    function LogoutButton(props) {
      return (
        <button onClick={props.onClick}>
          Logout
        </button>
      );
    }
    
    //元素变量button
    class LoginControl extends React.Component {
      constructor(props) {
        super(props);
        this.handleLoginClick = this.handleLoginClick.bind(this);
        this.handleLogoutClick = this.handleLogoutClick.bind(this);
        this.state = {isLoggedIn: false};
      }
    
      handleLoginClick() {
        this.setState({isLoggedIn: true});
      }
    
      handleLogoutClick() {
        this.setState({isLoggedIn: false});
      }
    
      render() {
        const isLoggedIn = this.state.isLoggedIn;
        let button;
        if (isLoggedIn) {
          button = <LogoutButton onClick={this.handleLogoutClick} />;
        } else {
          button = <LoginButton onClick={this.handleLoginClick} />;
        }
    
        return (
          <div>
            <Greeting isLoggedIn={isLoggedIn} />
            {button}  
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <LoginControl />,
      document.getElementById('root')
    );
    
  • && 运算符

    通过花括号包裹代码,你可以在 JSX 中嵌入任何表达式。这也包括 JavaScript 中的逻辑与 (&&) 运算符。

    function Mailbox(props) {
      const unreadMessages = props.unreadMessages;
      return (
        <div>
          <h1>Hello!</h1>
          {unreadMessages.length > 0 &&
            <h2>
              You have {unreadMessages.length} unread messages.
            </h2>
          }
        </div>
      );
    }
    
    const messages = ['React', 'Re: React', 'Re:Re: React'];
    ReactDOM.render(
      <Mailbox unreadMessages={messages} />,
      document.getElementById('root')
    );
    
  • 三目运算符

    render() {
      const isLoggedIn = this.state.isLoggedIn;
      return (
        <div>
          The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
        </div>
      );
    }
    //也可以用于较为复杂的表达式中,虽然看起来不是很直观
    render() {
      const isLoggedIn = this.state.isLoggedIn;
      return (
        <div>
          {isLoggedIn
            ? <LogoutButton onClick={this.handleLogoutClick} />
            : <LoginButton onClick={this.handleLoginClick} />
          }
        </div>
      );
    }
    
  • 阻止组件渲染

    function WarningBanner(props) {
      if (!props.warn) {
        return null;
      }
    
      return (
        <div className="warning">
          Warning!
        </div>
      );
    }
    
    class Page extends React.Component {
      constructor(props) {
        super(props);
        this.state = {showWarning: true};
        this.handleToggleClick = this.handleToggleClick.bind(this);
      }
    
      handleToggleClick() {
        this.setState(state => ({
          showWarning: !state.showWarning
        }));
      }
    
      render() {
        return (
          <div>
            <WarningBanner warn={this.state.showWarning} />
            <button onClick={this.handleToggleClick}>
              {this.state.showWarning ? 'Hide' : 'Show'}
            </button>
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <Page />,
      document.getElementById('root')
    );
    

    在组件的 render 方法中返回 null 并不会影响组件的生命周期。

列表和Key

我们使用 Javascript 中的 map() 方法来遍历数组,实现列表的渲染

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    //key 用于 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。
    //key最好是一个独一无二的字符串,通常使用数组当中每一项的id ,当元素没有确定 id 的时候,万不得已你可以使用元素索引 index 作为 key:
     //key 应该放在map方法当中,遍历的的数组内的就近组件或者元素之上
     // key会传递信息给 React ,但不会传递给你的组件
    <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')
);

表单

在 React 里,HTML 表单元素的工作方式和其他的 DOM 元素有些不同,这是因为表单元素通常会保持一些内部的 state。

在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()来更新。

受控组件:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('提交的名字: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          名字:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="提交" />
      </form>
    );
  }
}
  • textarea组件

    class EssayForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          value: '请撰写一篇关于你喜欢的 DOM 元素的文章.'
        };
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
        this.setState({value: event.target.value});
      }
    
      handleSubmit(event) {
        alert('提交的文章: ' + this.state.value);
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              文章:
              <textarea value={this.state.value} onChange={this.handleChange} />
            </label>
            <input type="submit" value="提交" />
          </form>
        );
      }
    }
    
  • select标签

    class FlavorForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {value: 'coconut'};
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
        this.setState({value: event.target.value});
      }
    
      handleSubmit(event) {
        alert('你喜欢的风味是: ' + this.state.value);
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              选择你喜欢的风味:
              <select value={this.state.value} onChange={this.handleChange}>
                <option value="grapefruit">葡萄柚</option>
                <option value="lime">酸橙</option>
                <option value="coconut">椰子</option>
                <option value="mango">芒果</option>
              </select>
            </label>
            <input type="submit" value="提交" />
          </form>
        );
      }
    }
    

    总的来说,这使得 <input type="text">, <textarea><select> 之类的标签都非常相似—它们都接受一个 value 属性,你可以使用它来实现受控组件。

    注意

    你可以将数组传递到 value 属性中,以支持在 select 标签中选择多个选项:

    <select multiple={true} value={['B', 'C']}>
    

    文件 input 标签

    在 HTML 中,<input type="file"> 允许用户从存储设备中选择一个或多个文件,将其上传到服务器,或通过使用 JavaScript 的 File API 进行控制。

    <input type="file" />
    

    因为它的 value 只读,所以它是 React 中的一个非受控组件。将与其他非受控组件在后续文档中一起讨论。

    处理多个输入

    当需要处理多个 input 元素时,我们可以给每个元素添加 name 属性,并让处理函数根据 event.target.name 的值选择要执行的操作。

    例如:

    class Reservation extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          isGoing: true,
          numberOfGuests: 2
        };
    
        this.handleInputChange = this.handleInputChange.bind(this);
      }
    
      handleInputChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
        this.setState({
          [name]: value    });
      }
    
      render() {
        return (
          <form>
            <label>
              参与:
              <input
                name="isGoing"            type="checkbox"
                checked={this.state.isGoing}
                onChange={this.handleInputChange} />
            </label>
            <br />
            <label>
              来宾人数:
              <input
                name="numberOfGuests"            type="number"
                value={this.state.numberOfGuests}
                onChange={this.handleInputChange} />
            </label>
          </form>
        );
      }
    }
    

    在 CodePen 上尝试

    这里使用了 ES6 计算属性名称的语法更新给定输入名称对应的 state 值:

    例如:

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

    等同 ES5:

    var partialState = {};
    partialState[name] = value;this.setState(partialState);
    

    另外,由于 setState() 自动将部分 state 合并到当前 state, 只需调用它更改部分 state 即可。

    受控输入空值

    受控组件上指定 value 的 prop 会阻止用户更改输入。如果你指定了 value,但输入仍可编辑,则可能是你意外地将 value 设置为 undefinednull

    下面的代码演示了这一点。(输入最初被锁定,但在短时间延迟后变为可编辑。)

    ReactDOM.render(<input value="hi" />, mountNode);
    
    setTimeout(function() {
      ReactDOM.render(<input value={null} />, mountNode);
    }, 1000);
    

    受控组件的替代品——非受控组件

状态提升

通常,多个组件需要反映相同的变化数据,这时我们建议将共享状态提升到最近的共同父组件中去。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 加载 React。-->
    <!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"。-->
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <!-- 加载我们的 React 组件。-->
    <!-- <script src="like_button.js"></script> -->

</head>

<body>
<div id="root"></div>

</body>
<script type="text/babel">
    //温度转换
    function toCelsius(fahrenheit) {
        return fahrenheit === ''?'':(fahrenheit - 32) * 5 / 9;
    }
    
    function toFahrenheit(celsius) {
        return celsius===''?'':(celsius * 9 / 5) + 32;
    }
    
    //判断税是否沸腾
    function Boil(props) {
        if (props.temp > 100) {
            return <h1>水沸腾了~</h1>
        }
        return props.temp!==''?<h1>水儿还在睡觉觉!</h1>:<h1>请在任一输入框输入温度值:</h1>
    }

    // 填写温度的表单组件, 状态提升
    function TempFrom(props) {
        function handleTempChange(e) {
            const reg = /^[0-9]+\.?[0-9]*$/;
            let v = e.target.value
            //利用正则判断输入框中是否数字
            let value = v.search(reg) !== -1? v :''

            props.handleChange(value)
        }

        return <div>
            <fieldset>
                <legend>填写{props.type === 'c'?'摄氏温度':'华氏温度'}:</legend>
                <input value={props.temp} onChange={handleTempChange}/>
            </fieldset>
        </div>
    }

    class App extends React.Component {
        constructor(props) {
            super(props);
            this.state = {  //初始化state状态
                temperature: '',
                type: 'c'
            }
        }
        //动态更新华氏温度
        handleC(v) {
            this.setState({
                temperature: v,
                type: 'c'
            })
        }
        //动态更新摄氏温度
        handleF(v) {
            this.setState({
                temperature: v,
                type: 'f'
            })
        }

        render() {
            //处理温度在线转换
            let type = this.state.type
            let temp = this.state.temperature
            let celsuis = type === 'c'?temp:toCelsius(temp)
            let fahrenheit = type === 'f'?temp:toFahrenheit(temp)
            return (
                <div>
                    <TempFrom
                        type='c'
                        temp={celsuis}
                        handleChange={this.handleC.bind(this)}
                    />
                    <TempFrom
                        type='f'
                        temp={fahrenheit}
                        handleChange={this.handleF.bind(this)}
                    />
                    <Boil temp={celsuis}/>
                </div>
            )
        }
    }

    ReactDOM.render(
        <App/>,
        document.getElementById('root')
    )
</script>

</html>

组合vs继承

React 有十分强大的组合模式。我们推荐使用组合而非继承来实现组件间的代码重用

在 Facebook,我们在成百上千个组件中使用 React。我们并没有发现需要使用继承来构建组件层次的情况。

——不建议使用继承

组合

  • 包含关系

    props.children:类似于vue当中的插槽

    使用一个特殊的 children prop 来将他们的子组件传递到渲染结果中

    <script type="text/babel">
        
        function Child(props) {
            return <div>
                {props.children}
            </div>
        }
        class App extends React.Component {
            constructor(props) {
                super(props);
                this.state = {
                    title:'children Props',
                    msg:'将他们的子组件传递到渲染结果中'
                }
            }
    
            render() {
                return (
                    <Child>
                        <h1>{this.state.title}使用</h1>
                        <p>{this.state.msg}</p>
                    </Child>
                )
            }
        }
    
    
        ReactDOM.render(
            <App/>,
            document.getElementById('root')
        )
    </script>
    

    少数情况下,你可能需要在一个组件中预留出几个“洞”。这种情况下,我们可以不使用 children,而是自行约定:将所需内容传入 props,并使用相应的 prop。

    类似于vue当中的具名插槽

    function SplitPane(props) {
      return (
        <div className="SplitPane">
          <div className="SplitPane-left">
            {props.left}
          </div>
          <div className="SplitPane-right">
            {props.right}
          </div>
        </div>
      );
    }
    
    function App() {
      return (
        <SplitPane
          left={
            <Contacts />
          }
          right={
            <Chat />
          } />
      );
    }
    

特例关系:

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
    </FancyBorder>
  );
}

function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}

组合也同样适用于以 class 形式定义的组件:

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
      {props.children}    </FancyBorder>
  );
}

class SignUpDialog extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSignUp = this.handleSignUp.bind(this);
    this.state = {login: ''};
  }

  render() {
    return (
      <Dialog title="Mars Exploration Program"
              message="How should we refer to you?">
        <input value={this.state.login}               onChange={this.handleChange} />        <button onClick={this.handleSignUp}>          Sign Me Up!        </button>      </Dialog>
    );
  }

  handleChange(e) {
    this.setState({login: e.target.value});
  }

  handleSignUp() {
    alert(`Welcome aboard, ${this.state.login}!`);
  }
}

React哲学

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值