组件 & Props的学习
组件允许你将 UI 拆分为独立可复用的代码片段,并对每个片段进行独立构思。
组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。
1.函数组件与 class 组件
1).定义组件最简单的方式就是编写 JavaScript 函数:
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
这段代码就可以称之为函数组件,首先接收了props(代表属性)参数,其次返回react元素。这类组件被称为“函数组件”,因为它本质上就是 JavaScript 函数。
2).class组件(使用 ES6 的 class)需要继承React.Component
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
注:class组件需要在类中的render()方法内返回react元素。上述两个组件在 React 里是等效的。
2.渲染组件
React 元素不仅可以使用dom标签也可以是用户自定义的组件:
dom标签
const element = <div />;
自定义标签
const element = <Welcome name="Sara" />;
当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)转换为单个对象传递给组件,这个对象被称之为 “props”。
这段代码会在页面上渲染 “Hello, Sara”:
function Welcome(props) { return <h1>Hello, {props.name}</h1>; } const element = <Welcome name="Sara" />; ReactDOM.render( element, document.getElementById(‘root‘) );
注意: 组件名称必须以大写字母开头。
React 会将以小写字母开头的组件视为原生 DOM 标签。例如,<div />
代表 HTML 的 div 标签,而 <Welcome />
则代表一个组件,并且需在作用域内使用 Welcome
。
我们可以重新使用函数组件和class组件进行重构计时器:
函数组件重构:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>函数组件计时器</title>
</head>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<script type="text/babel">
function Time(props){
return (
<div>
<h1>当前时间是:{props.date.toLocaleTimeString()}</h1>
</div>
);
}
function tick(){
ReactDOM.render(
<Time date={new Date()}/>,
document.getElementById(‘root‘)
)
}
setInterval(tick,1000);
</script>
<body>
<div id="root"></div>
</body>
</html>
class组件计时器:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>函数组件计时器</title>
</head>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<script type="text/babel">
class Time extends React.Component {
render(){
return (
<div>
<h1>Hello, world!</h1>
<h2>现在是 {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
/*function Time(props){
return (
<div>
<h1>当前时间是:{props.date.toLocaleTimeString()}</h1>
</div>
);
}*/
function tick(){
ReactDOM.render(
<Time date={new Date()}/>,
document.getElementById(‘root‘)
)
}
setInterval(tick,1000);
</script>
<body>
<div id="root"></div>
</body>
</html>
3.组合组件
组件可以在其输出中引用其他组件。这就可以让我们用同一组件来抽象出任意层次的细节。按钮,表单,对话框,甚至整个屏幕的内容:在 React 应用程序中,这些通常都会以组件的形式表示。
我们可以创建一个可以多次渲染 Func
组件的 App
组件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>react组合组件</title> </head> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script> <script type="text/babel"> function Func(props) { return <h1>hello,{props.name}</h1>; } class App extends React.Component { render(){ return ( <div> <Func name="Lisu" /> <Func name="Lisu" /> <Func name="Lisu" /> </div> ); } } const element = <App />; ReactDOM.render( element, document.getElementById(‘root‘) ); </script> <body> <div id="root"></div> </body> </html>
4.提取组件
将组件拆分为更小的组件。
function Comment(props) { return ( <div className="Comment"> <div className="UserInfo"> <img className="Avatar" src={props.author.avatarUrl} alt={props.author.name} /> <div className="UserInfo-name"> {props.author.name} </div> </div> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formatDate(props.date)} </div> </div> ); }
该组件用于描述一个社交媒体网站上的评论功能,它接收 author
(对象),text
(字符串)以及 date
(日期)作为 props。
该组件由于嵌套的关系,变得难以维护,且很难复用它的各个部分。因此,让我们从中提取一些组件出来。
1).首先提取Avatar(头像)部分:
function Avatar(props) { return ( <Avatar className="Avatar" src={props.user.avatarUrl} alt={props.user.name} /> ); }
2).替换Comment中的头像部分
function Comment(props) { return ( <div className="Comment"> <div className="UserInfo"> <Avatar user={props.author} /> <div className="UserInfo-name"> {props.author.name} </div> </div> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formatDate(props.date)} </div> </div> ); }
3).抽取UserInfo
组件
function UserInfo(props) { return ( <div className="UserInfo"> <Avatar user={props.user} /> <div className="UserInfo-name"> {props.user.name} </div> </div> ); }
4).替换UserInfo
function Comment(props) { return ( <div className="Comment"> <UserInfo user={props.author} /> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formatDate(props.date)} </div> </div> ); }
5.Props 的只读性
组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。
function sum(a, b) { return a + b; }
这样的函数被称为“纯函数”,因为该函数不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果。
function withdraw(account, amount) { account.total -= amount; }
这个函数则不是纯函数,因为它更改了自己的入参
React 非常灵活,但它也有一个严格的规则:所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。
原文:https://www.cnblogs.com/xsxqc/p/11398965.html