父子组件数据关系与状态提升
状态提升:两个组件(无父子关系)共享一个数据并同步数据变化,即将子组件中的数据提升到父组件中进行操作和管理,通过 props
传递给子组件
类组件调用(实例化)的时候,组件内部的状态是唯一且独立的,组件之间数据不共享
组件嵌套与调用,和类组件还是函数组件没有关系
组合与继承、CSS Module
React
目前还没有发现有需要组件继承的需求,因为通过 children
或者传递视图 React
元素的方式完全可以解决组件组合的问题,props
可以传递任何类型的数据,所以组合的方式完全可以替代继承方案
逻辑部分需要继承或者共用时,需要自己去写逻辑抽离的模块、函数、类,单独进行模块导入使用
// 1. 如果 Container 内部有内容,React 会在 props 内部增加 children 属性
// 2. 如果 Container 内部有非元素内容,children:非元素内容,如文本
// 3. 如果 Container 内部有单个元素内容,children:React 元素对象
// 4. 如果 Container 内部有多个元素内容,childre:[...(React 元素对象)]
// css module 模块化
import styles from './index.module.css'
class Container extends React.Component {
render() {
return (
<div className={styles.container}>
<div className="header">{this.props.header}</div>
<div className="sidebar">{this.props.sidebar}</div>
<div className="main">{this.props.main}</div>
</div>
);
}
}
class Header extends React.Component {
render() {
return <p>Header</p>;
}
}
class SideBar extends React.Component {
render() {
return <p>SideBar</p>;
}
}
class Main extends React.Component {
render() {
return <p>Main</p>;
}
}
class App extends React.Component {
render() {
return (
<Container header={<Header />} sidebar={<SideBar />} main={<Main />} />
);
}
}
ReactDOM.render(<App />, document.querySelector("#app"));
为什么 JSX 可以通过 props 传递视图元素、React 元素?
JSX
本质上都会转为 React
元素,视图通过 props
传递的机制比较像 vue
的插槽(slot
),React
本身就允许通过 props
传递任何类型的数据到子组件
function Modal(props) {
return (
<div>
<header>
<h1>{props.modalHeader}</h1>
</header>
<div className="content">{props.children}</div>
</div>
);
}
function Alert(props) {
return (
<Modal modalHeader={props.headerTitle}>
<p>{props.alertText}</p>
</Modal>
);
}
function WelcomeAlert(props) {
return <Alert headerTitle="Alert - 欢迎标题" alertText="Alert - 欢迎欢迎"></Alert>;
}
function LoginModal(props) {
return (
<Modal modalHeader="登录">
// 通过 props 将 JSX 传递给子组件
<form action="" method="post">
<p>
<button>登录</button>
</p>
</form>
</Modal>
);
}
function App() {
return (
<div>
<WelcomeAlert />
<LoginModal />
</div>
);
}
ReactDOM.render(<App />, document.querySelector("#app"));