Preact 实现的几个关键目标:
- 性能:快速与高效的渲染
- 大小:小,轻 (大约 3.5kb)
- 效率:高效的内存使用 (对象重复利用, 避免垃圾回收)
- 可理解性:可以几小时理解框架代码
- 兼容性:Preact 兼容大部分的 React API。 preact-compat 实现了更多的 react api 兼容
使用
import { h, render, Component } from "preact";
// 类组件
class App extends Component {
constructor() {
super();
this.state = { time: Date.now() };
}
render() {
let time = new Date(this.state.time).toLocaleTimeString();
return <h1>Hello, world! {time}!</h1>;
}
}
render(<App />, document.body);
// 函数组件
function MyComponent(props) {
return <div>My name is {props.name}.</div>;
}
// Usage
const App = <MyComponent name="John Doe" />;
render(App, document.body);
/**
* Renders: <div>My name is John Doe.</div>
*/
Preact 与 react 的不同:
1. preact render
在preact中可以这样写:
// Only works in Preact
class Foo extends Component {
state = { age: 1 };
render({ name }, { age }) {
return <div>Name: {name}, Age: {age}</div>;
}
}
通用写法:
// Works in both Preact and React
class Foo extends Component {
state = { age: 1 };
render() {
return <div>Name: {this.props.name}, Age: {this.state.age}</div>;
}
}
2. class
和 className 通用
在 preact 可以直接用 class, 更方便
// This:
<div class="foo" />
// ...is the same as:
<div className="foo" />
3. 用 onInput
替代 onChange
// React
<input onChange={e => console.log(e.target.value)} />
// Preact
<input onInput={e => console.log(e.target.value)} />
4. JSX-Constructor
// 以前这么写:
let foo = <div id="foo">Hello!</div>;
// 现在可以这么写:
var foo = h('div', {id:"foo"}, 'Hello!');
或者:
// 以前这么写:
React.createElement(
'a',
{ href:'/' },
React.createElement('span', null, 'Home')
);
// 现在可以这么写:
h(
'a',
{ href:'/' },
h('span', null, 'Home')
);
/**
* Renders:<a href="/">Home</a>
*/
Fragment
import { Fragment, render } from 'preact';
function TodoItems() {
return (
<Fragment>
<li>A</li>
<li>B</li>
<li>C</li>
</Fragment>
)
}
const App = (
<ul>
<TodoItems />
<li>D</li>
</ul>
);
render(App, container);
// Renders:
// <ul>
// <li>A</li>
// <li>B</li>
// <li>C</li>
// <li>D</li>
// </ul>
creatRef
class Foo extends Component {
state = {
width: 0,
height: 0,
};
ref = createRef();
componentDidMount() {
// For safety: Check if a ref was supplied
if (this.ref.current) {
const dimensions = this.ref.current.getBoundingClientRect();
this.setState({
width: dimensions.width,
height: dimensions.height,
});
}
}
render(_, { width, height }) {
return (
<div ref={this.ref}>
Width: {width}, Height: {height}
</div>
);
}
}
Callback Refs
class Foo extends Component {
ref = null;
setRef = (dom) => this.ref = dom;
componentDidMount() {
console.log(this.ref);
// Logs: [HTMLDivElement]
}
render() {
return <div ref={this.setRef}>foo</div>
}
}
setState
this.state = { counter: 0 };
this.setState(prevState => {
// Alternatively return `null` here to abort the state update
return { counter: prevState.counter++ };
});
createContext
const Theme = createContext('light');
function ThemedButton(props) {
return (
<Theme.Consumer>
{theme => {
return <button {...props} class={'btn ' + theme}>Themed Button</button>;
}}
</Theme.Consumer>
);
}
function App() {
return (
<Theme.Provider value="dark">
<SomeComponent>
<ThemedButton />
</SomeComponent>
</Theme.Provider>
);
}
其它
Forms:https://preactjs.com/guide/v10/forms
Hooks:https://preactjs.com/guide/v10/hooks
context:https://preactjs.com/guide/v10/context
react to preact
针对 preact is not defined 的问题
在 .babelrc 新增:
.babelrc
针对 h is not defined 的问题
在webpack配置文件新增:
webpack 配置文件
网友评论