前端的文件目录树,除了特定的配置文件之外,其他都可以按照自己的项目需求创建,但是要层次结构分明,一般情况下,我们按照组件功能或者路由来生成项目的目录树(示例在src目录下新建一个components文件夹,然后在其中新建组件)。
React中的组件都是以JS文件的形式呈现的。
新建HeaderNav组件,那就新建一个header-nav.js
React中组件的具体代码形式是一个class类,比如:
class HeaderNav {
// code
}
export default HeaderNav
这个类和普通的JS的类没有什么区别,那么如何区分组件类和普通的类。
React封装了一个Component类,在其中封装了React提供的组件的基本操作,声明一个普通的类,让其继承于Component类,那么这个类就会被当做一个组件去使用,也可以调用React提供给组件的所有属性和方法。
import React from 'react'
class HeaderNav extends React.Component {
render() {
return <h1>我是一小段测试代码</h1>;
}
}
export default HeaderNav
一般情况下,框架中调用组件至少两种方式,父组件调用子组件和路由调用组件。我们先说父组件调用子组件(路由单独介绍)。
// App.js
import HeaderNav from './components/header-nav.js'
// App.js
...
class App extends Component {
render() {
return (
<div className="App">
<HeaderNav />
</div>
);
}
}
...
上面的组件创建和调用中,组件的HTML结构声明在JS代码中,被一个r ender函数返回。这种结构声明的方式就是React的核心之一,JSX语法。render函数是ReactDOM对象的一个方法,React使用它解析JSX语法并渲染在DOM上。
一、 根组件
React中只有一个根节点(在一个已有项目中引入react除外),这个根节点在"public/index.html"中,如果要将某个结构渲染在浏览器上,必须使用ReactDOM.render函数。
当然这个配置是在安装项目时默认就有的,在"public/index.html"中有一个id为"root"的div,在"src/index.js"中,导入了App组件,并使用ReactDOM.render()函数将其渲染到了"root"中:
// public/index.html
...
<div id="root">div>
...
// src/index.js
...
import App from './App'
...
...
ReactDOM.render(<App />, document.getElementById('root'));
...
二、子组件
每一个组建类中都要有一个render函数,这个render函数返回一个JSX语法声明的元素,就是当前组件的结构代码。
React中,由JSX语法声明结构代码(HTML),之后用React语法调用。
一、JSX
JSX允许在JS代码中直接编写HTML结构代码。
// header-nav.js
import React from 'react'
// 使用JSX语法,用一个变量承接一个JSX元素
const el = <h1>取次花丛懒回顾,半缘修道半缘君。</h1>;
class HeaderNav extends React.Component {
render() {
return el; // 直接调用el变量
}
}
export default HeaderNav
// header-nav.js
...
// 如果元素结构较为复杂,为了避免不必要的bug,我们要将JSX语法写在一对小括号中
const el = (
<div>
<p>曾经沧海难为水</p>
<p>除去巫山不是云</p>
<p>取次花丛懒回顾</p>
<p>半缘修道半缘君</p>
</div>
);
...
// header-nav.js
...
const arr = ['取次花丛懒回顾','半缘修道半缘君'];
const el = (
<div>
<p>{arr[0]}</p>
<p>{arr[1]}</p>
</div>
);
...
// header-nav.js
import React from 'react'
function Message() {
return (<div>
<p>取次花丛懒回顾</p>
<p>半缘修道半缘君</p>
</div>);
}
class HeaderNav extends React.Component {
render() {
return (
<div>
<Message />
</div>
);
}
}
export default HeaderNav
在上面的示例中,Message就是一个被封装的模块。Message被封装后可能会被重复调用,每次调用时,内部展示的内容可能都是不定的。所以我们可以在调用Message时向其传参。
// header-nav.js
import React from 'react'
// 封装Message模块,并接收参数
function Message(props) {
return (<div>
<p>{props.arr[0]}</p>
<p>{props.arr[1]}</p>
</div>);
}
class HeaderNav extends React.Component {
render() {
return (
<div>
<Message arr={['身无彩凤双飞翼','心有灵犀一点通']} />
<Message arr={['天长地久有时尽','此恨绵绵无绝期']} />
</div>
);
}
}
export default HeaderNav
Message模块被复用,并且再被复用时接收了动态的数据。
注:
二、React.createElement()函数
JSX声明元素本质上是React对象的createElement()函数提供的语法糖。
// JSX:
const el = <h1></h1>;
// 本质:
React.createElement('h1');
所以如果要在某个JS文件中编写JSX语法,必须要提前引入React。
/*
React.createElement(elName,props,...children);
elName: 要新建的模块的名称;
props: 属性列表;(具体请参照文档)
children: 子元素列表;
*/
参考文档:
官方文档中对于项目目录树的说明