10-框架-React
React框架是一个非常流行的前端框架,它的主要特点是组件化和声明式编程。React框架允许开发人员将UI划分为独立的组件,这些组件可以在不同的应用程序中重复使用。React还提供了一种声明式编程模型,使得开发人员可以更加专注于UI的实现,而不是底层的实现细节。
在本文中,我们将介绍React框架的一些特性,包括函数组件、受控/非受控组件、异步组件、HOC、Portals以及几种高级模式与应用场景。
函数组件
React组件可以是类组件或函数组件。函数组件是一种更简单的方式来定义组件,它只是一个JavaScript函数,接收一些属性作为输入,并返回一个React元素作为输出。函数组件通常比类组件更简洁,因为它们不需要维护状态或实现生命周期方法。
以下是一个简单的函数组件示例,它接收一个名字属性,并返回一个包含该名称的标题元素:
import React from 'react';
interface Props {
name: string;
}
const Title: React.FC<Props> = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};
受控/非受控组件
在React中,表单元素是一种特殊的组件类型,它们需要维护自己的状态。React中的表单元素可以是受控组件或非受控组件。
受控组件是指那些表单元素,其值受React组件的状态控制。也就是说,当用户输入时,React组件会更新其状态,并重新渲染该组件。以下是一个受控组件的示例:
import React, { useState } from 'react';
const ControlledInput = () => {
const [value, setValue] = useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
return (
<div>
<input type="text" value={value} onChange={handleChange} />
<p>You typed: {value}</p>
</div>
);
};
非受控组件是指那些表单元素,其值不受React组件的状态控制。这意味着,当用户输入时,表单元素会自己维护其值,并且React组件无法访问该值。以下是一个非受控组件的示例:
import React, { useRef } from 'react';
const UncontrolledInput = () => {
const inputRef = useRef<HTMLInputElement>(null);
const handleClick = () => {
console.log('Input value:', inputRef.current?.value);
};
return (
<div>
<input type="text" ref={inputRef} />
<button onClick={handleClick}>Get value</button>
</div>
);
};
异步组件
在React中,异步组件是指那些需要在渲染时才会加载的组件。这通常用于延迟加载大型组件或可选组件,以提高应用程序的性能。
React支持两种异步组件加载方式:使用动态导入和使用React.lazy。以下是使用React.lazy的示例:
import React, { lazy, Suspense } from 'react';
const LazyComponent = lazy(() => import('./LazyComponent'));
const App = () => {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
};
HOC
HOC(Higher-Order Component)是一种设计模式,用于增强现有组件的功能。HOC本质上是一个函数,它接收一个组件作为参数,并返回一个新的增强组件。
以下是一个简单的HOC示例,它将一个计数器属性添加到现有组件中:
import React from 'react';
interface Props {
counter: number;
}
const withCounter = <P extends object>(Component: React.ComponentType<P>) => {
return (props: P & Props) => {
const { counter, ...rest } = props as Props;
return <Component {...rest as P} counter={counter + 1} />;
};
};
const MyComponent = ({ counter }: Props) => {
return <div>Counter value: {counter}</div>;
};
const EnhancedComponent = withCounter(MyComponent);
Portals
Portals是一种将子元素渲染到父元素之外的技术。这对于在应用程序中创建弹出窗口或模态框非常有用。
以下是一个简单的Portals示例,它将一个组件渲染到body元素之外:
import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
interface Props {
onClose: () => void;
}
const Modal: React.FC<Props> = ({ children, onClose }) => {
const el = document.createElement('div');
useEffect(() => {
document.body.appendChild(el);
return () => {
document.body.removeChild(el);
};
}, [el]);
return ReactDOM.createPortal(
<div>
<div>{children}</div>
<button onClick={onClose}>Close</button>
</div>,
el,
);
};
const App = () => {
const handleClose = () => {
console.log('Modal closed');
};
return (
<div>
<h1>My App</h1>
<Modal onClose={handleClose}>This is a modal</Modal>
</div>
);
};
几种高级模式与应用场景
除了上述特性之外,React还有一些高级模式和应用场景,包括:
- Render Props:一种模式,其中组件通过一个函数属性来共享其状态和逻辑。
- Context API:一种在组件树中共享数据的方式。
- Redux:一种状态管理库,用于在大型应用程序中管理复杂的状态。
- React Router:一种用于在单页应用程序中管理路由的库。
以下是一个使用Render Props的示例,其中一个组件通过一个函数属性来共享其状态和逻辑:
import React, { useState } from 'react';
interface Props {
render: (state: State, actions: Actions) => React.ReactNode;
}
interface State {
counter: number;
}
interface Actions {
increment: () => void;
}
const Counter: React.FC<Props> = ({ render }) => {
const [counter, setCounter] = useState(0);
const increment = () => {
setCounter(counter + 1);
};
const state = { counter };
const actions = { increment };
return <div>{render(state, actions)}</div>;
};
const App = () => {
return (
<div>
<Counter
render={({ counter }, { increment }) => (
<div>
<p>Counter value: {counter}</p>
<button onClick={increment}>Increment</button>
</div>
)}
/>
</div>
);
};
总结
React框架是一个非常强大和灵活的前端框架,它提供了许多特性和工具,使得开发人员可以更加轻松地构建高质量的UI组件。在本文中,我们介绍了React的一些特性,包括函数组件、受控/非受控组件、异步组件、HOC、Portals以及几种高级模式和应用场景。我们希望这些示例可以帮助您更好地理解React框架,并在您的下一个项目中使用它们。
转载自:https://juejin.cn/post/7224903364386652197