1.react-copy-to-clipboard
复制到剪贴板 React 组件
npm install --save react-copy-to-clipboard
使用案例:
import React, { useState, useEffect } from 'react';
import {CopyToClipboard} from 'react-copy-to-clipboard';
import { connect } from 'react-redux';
function Family(props) {
const [count, setCount] = useState(0);
const [value,setValue] = useState("");
const [copied,setCopied] = useState(false);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<input value={value} onChange={({target: {value}}) => {
setValue(value);
setCopied(false);
}} />
<CopyToClipboard text={value}
onCopy={() => setCopied(true)}>
<button>复制</button>
</CopyToClipboard>
{copied ? <span style={{color: 'red'}}>Copied.</span> : null}
</div>
);
}
export default connect(state=>state)(Family)
2.react-json-view
RJV 是一个 React 组件,用于显示和编辑 javascript 数组和 JSON 对象。 该组件提供了一个响应式界面,用于在 Web 浏览器中显示数组或 JSON
npm install --save react-json-view
使用案例:
import React, { useState, useEffect } from 'react';
import ReactJson from 'react-json-view';
import { connect } from 'react-redux';
function Family(props) {
const [data, setData]= useState<string>(''); // 举例 `{"code":200}
// JSON格式化
function stringToJson(_json = '') {
console.log(_json);
let json = {'message': '当前json格式错误!'};
if (_json) {
try {
json = JSON.parse(_json);
} catch (e) {
console.log('Error', '当前json格式错误!');
}
} else {
json = {'message': ''};
}
return json;
}
return (
<>
<ReactJson style={{width: '100%', height: 'calc(100vh - 370px)', overflow: 'auto'}} src={stringToJson(data)} />
</>
);
}
export default connect(state=>state)(Family)
3.react-infinite-scroll-component
只需 4.15 kB 即可消除所有无限滚动问题的组件!添加了下拉刷新功能。一个真正有效的无限滚动,而且集成起来超级简单
npm install --save react-infinite-scroll-component
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import InfiniteScroll from "react-infinite-scroll-component";
const style = {
height: 30,
border: "1px solid green",
margin: 6,
padding: 8
};
function Family(props) {
const [items,setItems] = useState(Array.from({ length: 20 }));
const fetchMoreData = () => {
setTimeout(() => {
setItems(items.concat(Array.from({ length: 20 })));
}, 1500);
};
return (
<>
<h1>demo: react-infinite-scroll-component</h1>
<hr />
<InfiniteScroll
dataLength={items.length}
next={fetchMoreData}
hasMore={true}
loader={<h4>Loading...</h4>}
>
{items.map((i, index) => (
<div style={style} key={index}>
div - #{index}
</div>
))}
</InfiniteScroll>
</>
);
}
export default connect(state=>state)(Family)
4. react-highlight-words
React 组件以突出显示较大文本正文中的单词。
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import Highlighter from "react-highlight-words";
function Family(props) {
return (
<div>
<Highlighter
highlightClassName="YourHighlightClass"
searchWords={["and", "or", "the"]}
autoEscape={true}
textToHighlight="The dog is chasing the cat. Or perhaps they're just playing?"
/>
</div>
);
}
export default connect(state=>state)(Family)
5.react-axios-http
这是一款结合axios和react的封装请求库, 主要解决了请求调用处理的统一和接口的统一管理, 以及在项目中的接口便捷调用
初始化
// ./http
import http, { combineApi } from "react-axios-http"
const apis = {
// demo
get: {
// get 默认
url: `/projectManage/show`,
//余下参数配置支持axios中的参数
}
post: {
// post
url: `/projectManage/show`,
method: 'post',
// isFormData: true 默认false
// 是否需要以formData形式传参
// isQuery: true 默认false
// post请求下,是否以url Query方式 ?pageNum=1&pageSize=10,
//余下参数配置支持axios中的参数
},
put: {
// put
url: `/projectManage/show`,
method: 'put',
// isFormData: true 默认false
// 是否需要以formData形式传参
// isQuery: true 默认false
// put请求下,是否以url Query方式 ?pageNum=1&pageSize=10
//余下参数配置支持axios中的参数
},
delete: {
// delete
url: `/projectManage/show`,
method: 'delete',
//余下参数配置支持axios中的参数
},
getJsonp: {
// jsonp
url: `/projectManage/show`,
method: 'getJsonp',
},
};
/* combineApi合并apis,作用域。
const IO = http(combineApi({
apis_1: apis,
apis_2: apis,
apis_3: apis,
},
true/false 默认true,作用域开启
)); */
const IO = http(apis);
// const IO = http(apis, {
// /* {opt} 默认可不传 */
// // 高级模式下的数据返回结果处理方式
// resultMode: 'native',// 可选array, 默认已设置native
// prefix: '', // 接口统一前缀
// 余下参数配置支持axios中的参数
// });
IO.interceptors.request.use(
config => {
console.log(config, 'interceptors request');
return config;
},
error => Promise.reject(error),
);
IO.interceptors.response.use(
response => {
console.log(response, 'interceptors response');
return response;
},
error => Promise.reject(error),
);
export default IO;
项目中基本使用方式
// 上面文件
import IO from './http'
const opt = {
key1: 'value1',
key2: 'value2',
}
const handler = (res) => {
// res为返回的结果。
return res;
}
// IO.getxxx(opt, handler)
// opt是传的参数,不需要传的可不写;
// handler 是对返回结果的二次加工,可不写;
IO.getxxx(opt, handler)
.then(res => {
// do something
});
// 如无参数,直接对返回结果的二次加工
IO.getxxx(handler)
.then(res => {
// do something
});
IO.getxxx().then(res => {
// do something
});
基本使用说明
- 默认get请求
- 导出文件 import IO from './http'
- 接口请求使用,直接IO.getxxx(),
- getxxx为apis中一接口名
- IO.getxxx(opt, handler),()中get和post请求无参数可为(空)
- handler 是对返回结果的二次加工,可不写;
- opt 此参数为post和get请求参数,类型皆为对象,如
- IO.getxxx({
- key: value,
- key: value,
- }, handler)
具体使用请参考 example目录;
高级使用方式
模仿react-redux方式
// 父组件或者根组件
import { ProviderApi } from "react-axios-http";
import apis from './http'
import Child from './Child'
ReactDOM.render(
<ProviderApi apis={apis}>
<Child />
</ProviderApi>)
document.getElementById("container")
);
//子组件
import React, { Component } from 'react'
import { connectApi } from "react-axios-http";
// 高级处理模式1 resultMode = 'native';默认
// 支持装饰器写法
// 1、@connectApi
// 2、@connectApi('apis_1')
// 3、@connectApi(Child,'apis_1')
class Child extends Component {
// 使用方式1
getFetch = async () => {
const { postxxx } = this.props;
const res = await postxxx(/*对象参数*/, /* handler 二次加工函数,可不写 */);
// 如无参数,直接对返回结果的二次加工
// const res = await postxxx(/* handler 二次加工函数,可不写 */);
//to do something
}
// 使用方式2
getFetch = () => {
const { postxxx } = this.props;
postxxx(/*对象参数*/, /* handler 二次加工函数,可不写 */)
// 如无参数,直接对返回结果的二次加工
// postxxx(/* handler 二次加工函数,可不写 */)
.then(res => {
//to do something
});
}
render() {
return (
<div onClick={this.getFetch}>
</div>
)
}
}
export default connectApi(Child);
// 高级处理模式2 resultMode = 'array,
// 返回一个数组,错误优先处理方式
class Child extends Component {
// 使用方式1
getFetch = async () => {
const { postxxx } = this.props;
const [err, res] = await postxxx(/*对象参数*/, /* handler 二次加工函数,可不写 */);
// 如无参数,直接对返回结果的二次加工
// const [err, res] = await postxxx(/* handler 二次加工函数,可不写 */);
// err参数不为空则说明请求出现请求异常或者错误
if (!err) {
//to do something
}
}
// 使用方式2
getFetch = () => {
const { postxxx } = this.props;
postxxx(/*对象参数*/, /* handler 二次加工函数,可不写 */)
.then(([err, res]) => {
if (!err) {
//to do something
}
});
}
render() {
return (
<div onClick={this.getFetch}>
</div>
)
}
}
export default connectApi(Child);
6.react-hot-loader
将应用程序标记为可热重载。 (更喜欢使用热助手,请参阅下面的迁移详细信息)。 这种低级方法可以让您制作 hot imports__,而不是导出。
import React from 'react';
import ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import App from './containers/App';
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('root'),
);
};
render(App);
// webpack Hot Module Replacement API
if (module.hot) {
// keep in mind - here you are configuring HMR to accept CHILDREN MODULE
// while `hot` would configure HMR for the CURRENT module
module.hot.accept('./containers/App', () => {
// if you are using harmony modules ({modules:false})
render(App);
// in all other cases - re-require App manually
render(require('./containers/App'));
});
}
7.react-hotkeys-hook
用于在组件中使用键盘快捷键的 React 钩子
npm i react-hotkeys-hook
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { useHotkeys } from 'react-hotkeys-hook';
function Family(props) {
const [count, setCount] = useState(0);
useHotkeys('ctrl+k', () => setCount(prevCount => prevCount + 1))
return (
<>
<p>You clicked {count} times</p>
</>
);
}
export default connect(state=>state)(Family)
8.react-lazyload
延迟加载您的组件、图像或任何对性能很重要的东西
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import LazyLoad from 'react-lazyload';
import imageUrl from '../../assets/images/1.png';
function Family(props) {
return (
<>
<LazyLoad once height={200} offset={100}>
<img src={imageUrl} alt="" width="200" height="200"/>
</LazyLoad>
</>
);
}
export default connect(state=>state)(Family)
9.react-markdown
这个包是一个 React 组件,可以给它一个 markdown 字符串,它将安全地呈现给 React 元素。你可以传递插件来改变 markdown 转换为 React 元素的方式,并传递将被使用的组件而不是普通的 HTML 元素
10.react-syntax-highlighter
React 的语法高亮组件
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import ReactMarkdown from 'react-markdown'
import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'
import {dark} from 'react-syntax-highlighter/dist/esm/styles/prism'
const markdown = `Here is some JavaScript code:
~~~js
console.log('It works!')
~~~
`
function Family(props) {
return (
<>
<ReactMarkdown
children={markdown}
components={{
code({node, inline, className, children, ...props}) {
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<SyntaxHighlighter
children={String(children).replace(/\n$/, '')}
style={dark}
language={match[1]}
PreTag="div"
{...props}
/>
) : (
<code className={className} {...props}>
{children}
</code>
)
}
}}
/>
</>
);
}
export default connect(state=>state)(Family)
11.react-window
用于高效渲染大型列表和表格数据的 React 组件 更多
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { FixedSizeList as List } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";
const Row = ({ index, style }) => (
<div className={index % 2 ? "ListItemOdd" : "ListItemEven"} style={style}>
Row {index}
</div>
);
`
function Family(props) {
return (
<>
<AutoSizer>
{({ height, width }) => (
<List
className="List"
height={height}
itemCount={1000}
itemSize={35}
width={width}>
{Row}
</List>
)}
</AutoSizer>
</>
);
}
export default connect(state=>state)(Family)
12.react-beautiful-dnd
使用 React 对列表进行漂亮且易于访问的拖放操作
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
// fake data generator
const getItems = count =>
Array.from({ length: count }, (v, k) => k).map(k => ({
id: `item-${k}`,
content: `item ${k}`
}));
// a little function to help us with reordering the result
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
const grid = 8;
const getItemStyle = (isDragging, draggableStyle) => ({
// some basic styles to make the items look a bit nicer
userSelect: "none",
padding: grid * 2,
margin: `0 0 ${grid}px 0`,
// change background colour if dragging
background: isDragging ? "lightgreen" : "grey",
// styles we need to apply on draggables
...draggableStyle
});
const getListStyle = isDraggingOver => ({
background: isDraggingOver ? "lightblue" : "lightgrey",
padding: grid,
width: 250
});
class App extends Component {
constructor(props) {
super(props);
this.state = {
items: getItems(10)
};
this.onDragEnd = this.onDragEnd.bind(this);
}
onDragEnd(result) {
// dropped outside the list
if (!result.destination) {
return;
}
const items = reorder(
this.state.items,
result.source.index,
result.destination.index
);
this.setState({
items
});
}
// Normally you would want to split things out into separate components.
// But in this example everything is just done in one place for simplicity
render() {
return (
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId="droppable">
{(provided, snapshot) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
style={getListStyle(snapshot.isDraggingOver)}
>
{this.state.items.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
{item.content}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
);
}
}
// Put the thing into the DOM!
ReactDOM.render(<App />, document.getElementById("root"));
13.react-beforeunload
侦听 beforeunload 窗口事件的 React 组件和钩子。
import { Beforeunload } from 'react-beforeunload';
class Example extends React.Component {
state = { value: '' };
render() {
return (
<>
{this.state.value !== '' && (
<Beforeunload onBeforeunload={(event) => event.preventDefault()} />
)}
<input
onChange={(event) => this.setState({ value: event.target.value })}
value={this.state.value}
/>
</>
);
}
}
14.react-cookie
React 的通用 cookie
// Root.jsx
import React from 'react';
import App from './App';
import { CookiesProvider } from 'react-cookie';
export default function Root() {
return (
<CookiesProvider>
<App />
</CookiesProvider>
);
}
// App.jsx
import React from 'react';
import { useCookies } from 'react-cookie';
import NameForm from './NameForm';
function App() {
const [cookies, setCookie] = useCookies(['name']);
function onChange(newName) {
setCookie('name', newName, { path: '/' });
}
return (
<div>
<NameForm name={cookies.name} onChange={onChange} />
{cookies.name && <h1>Hello {cookies.name}!</h1>}
</div>
);
}
export default App;
15.react-split-pane-next
Split-Pane React 组件,可以垂直或水平嵌套或拆分
import SplitPane, { Pane } from 'react-split-pane-next';
<SplitPane split="vertical">
<Pane initialSize="200px">You can use a Pane component</Pane>
<div>or you can use a plain old div</div>
<Pane initialSize="25%" minSize="10%" maxSize="500px">
Using a Pane allows you to specify any constraints directly
</Pane>
</SplitPane>;
16.video-react
Video.React 是一个使用 React 库从头开始为 HTML5 世界构建的网络视频播放器。
import React from 'react';
import { Player } from 'video-react';
export default props => {
return (
<Player>
<source src="https://media.w3.org/2010/05/sintel/trailer_hd.mp4" />
</Player>
);
};