AJAX AND APIs
1、在React中如何调用AJAX?
使用AJAX库:Axios, jQuery AJAX,the browser built-in window.fetch
2、应该在那个生命周期函数中调用AJAX获取数据?
在生命周期函数componentDidMount()中调用AJAX,并且可以调用SetState()设置state
//API返回的JSON对象
{
"items": [
{ "id": 1, "name": "Apples", "price": "$2" },
{ "id": 2, "name": "Peaches", "price": "$5" }
]
}
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
items: []
};
}
componentDidMount() {
fetch("https://api.example.com/items")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result.items
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { error, isLoaded, items } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
{items.map(item => (
<li key={item.name}>
{item.name} {item.price}
</li>
))}
</ul>
);
}
}
}
Babel, JSX, and Build Steps
1、在React中一定要使用JSX语法吗?
可以不使用
2、在React中一定要使用ES6(+)语法吗?
不一定
3、在JSX中如何书写注释?----{/*....*/}
<div>
{/* Comment goes here */}
Hello, {name}!
</div>
<div>
{/* It also works
for multi-line comments. */}
Hello, {name}!
</div>
Passing Functions to Components---传递函数到组件里面
1、如何将一个事件传递给组件?
将事件作为组件的props属性
//已有组件
<button onClick={this.handleClick}>
2、如何将函数绑定到组件实例中?
使用不同的语法,绑定方式不一样
//1、绑定在constructor函数中(ES2015,也就是ES6)
//推荐使用这种方式
class Foo extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
//2、render()函数中的事件为箭头函数
class Foo extends Component {
handleClick() {
console.log('Click happened');
}
render() {
return <button onClick={() => this.handleClick()}>Click Me</button>;
}
}
//3、绑定在render()函数中
//缺点:每次
class Foo extends Component {
handleClick() {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
}
}
3、在render()函数中可以使用箭头函数吗?
在不考虑性能问题下,通常情况是可以的
4、在组件类中为什么将传递给组件的函数需要绑定?
obj.method();
var method = obj.method;
method();
像上面两个例子得出的结果可能就不一样,如果method中含有this对象
5、为什么每次组件渲染的时候,都会调用绑定的函数
render() {
// Wrong: handleClick is called instead of passed as a reference!
return <button onClick={this.handleClick()}>Click Me</button>
}
render() {
// Correct: handleClick is passed as a reference!
return <button onClick={this.handleClick}>Click Me</button>
}
6、如何给事件或者回调函数传递参数
<button onClick={() => this.handleClick(id)} />
//和上面的写法一样
<button onClick={this.handleClick.bind(this, id)} />
1)通过箭头函数传递参数
//example,通过箭头函数传递参数
const A = 65 // ASCII character code
class Alphabet extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
justClicked: null,
letters: Array.from({length: 26}, (_, i) => String.fromCharCode(A + i))
};
}
handleClick(letter) {
this.setState({ justClicked: letter });
}
render() {
return (
<div>
Just clicked: {this.state.justClicked}
<ul>
{this.state.letters.map(letter =>
<li key={letter} onClick={() => this.handleClick(letter)}>
{letter}
</li>
)}
</ul>
</div>
)
}
}
2)使用data-attributes
const A = 65 // ASCII character code
class Alphabet extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
justClicked: null,
letters: Array.from({length: 26}, (_, i) => String.fromCharCode(A + i))
};
}
handleClick(e) {
this.setState({
justClicked: e.target.dataset.letter
});
}
render() {
return (
<div>
Just clicked: {this.state.justClicked}
<ul>
{this.state.letters.map(letter =>
<li key={letter} data-letter={letter} onClick={this.handleClick}>
{letter}
</li>
)}
</ul>
</div>
)
}
}
7、如何阻止一个函数调用得太快或者连续调用
比如在onClick或者onScroll中,不想让回调函数立即执行,可以设置callback的执行时机
1)throttle
-----阻止点击事件在1秒内多次执行
import throttle from 'lodash.throttle';
class LoadMoreButton extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.handleClickThrottled = throttle(this.handleClick, 1000);
}
componentWillUnmount() {
this.handleClickThrottled.cancel();
}
render() {
return <button onClick={this.handleClickThrottled}>Load More</button>;
}
handleClick() {
this.props.loadMore();
}
}
2)debounce
----规定函数自上次被调用后相隔一定时间才能再次被调用
import debounce from 'lodash.debounce';
class Searchbox extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.emitChangeDebounced = debounce(this.emitChange, 250);
}
componentWillUnmount() {
this.emitChangeDebounced.cancel();
}
render() {
return (
<input
type="text"
onChange={this.handleChange}
placeholder="Search..."
defaultValue={this.props.value}
/>
);
}
handleChange(e) {
// React pools events, so we read the value before debounce.
// Alternately we could call `event.persist()` and pass the entire event.
// For more info see reactjs.org/docs/events.html#event-pooling
this.emitChangeDebounced(e.target.value);
}
emitChange(value) {
this.props.onChange(value);
}
}
component state
1、setState()有什么用
用于更新component的state,当state发生变化的时候,component会re-render
2、state和props的区别
相同点:都是普通的js object;都会影响组件的render
不同点:props是在component上的属性,用于值不发生变化,有父组件传递过来的属性等;而state用于变化的,和Ui发生交互,在组件类内操作
3、setState()返回一个错误的值
setState()是一个异步函数,在调用setState之后马上调用this.state不会是更新的值,可以用updater替换object如果需要当前值的话
incrementCount() {
// Note: this will *not* work as intended.
//参数是object
this.setState({count: this.state.count + 1});
}
handleSomething() {
// Let's say `this.state.count` starts at 0.
this.incrementCount();
this.incrementCount();
this.incrementCount();
// When React re-renders the component, `this.state.count` will be 1, but you expected 3.
// This is because `incrementCount()` function above reads from `this.state.count`,
// but React doesn't update `this.state.count` until the component is re-rendered.
// So `incrementCount()` ends up reading `this.state.count` as 0 every time, and sets it to 1.
// The fix is described below!
}
4、如何利用当前state来更新state的值
将setState()中的参数用function取代object,这样保证每次调用的时候都是最新的state值
5、setState()中的参数为object和function的区别
参数为updater,可以保证在updater里面读取到的state就是当前值,可以连续调用而不发生冲突
incrementCount() {
this.setState((state) => {
// Important: read `state` instead of `this.state` when updating.
return {count: state.count + 1}
});
}
handleSomething() {
// Let's say `this.state.count` starts at 0.
this.incrementCount();
this.incrementCount();
this.incrementCount();
// If you read `this.state.count` now, it would still be 0.
// But when React re-renders the component, it will be 3.
}
styling and css
1、如何给组件添加class
将字符串类型作为className的值
render() {
return <span className="menu navigation-menu">Menu</span>
}
普遍情况下css的class依赖props 或者state的值来添加
render() {
let className = 'menu';
if (this.props.isActive) {
className += ' menu-active';
}
return <span className={className}>Menu</span>
}
2、可以在组件内书写行内样式吗?
可以
const divStyle = {
color: 'blue',
backgroundImage: 'url(' + imgUrl + ')',
};
function HelloWorldComponent() {
return <div style={divStyle}>Hello World!</div>;
}
// Result style: '10px'
<div style={{ height: 10 }}>
Hello World!
</div>
// Result style: '10%'
<div style={{ height: '10%' }}>
Hello World!
</div>
3、可以在react中使用animation吗?
可以
1)首先安装react-transition-group库
2)库react-transition-group中的components
Transition CSSTransition TransitionGroup
1)<Transition>组件-----跟踪state的变化,有四个状态,通过属性in来改变状态---boolean,由false->true是enteing->entered,由true->false是exiting->exited,timeout属性设置由entering到entered所要花费的时间,
entering
entered
exiting
exited
具有的属性pops
A、children----function child可以作为React的element
<Transition timeout={150}>
{(status) => (
<MyComponent className={`fade fade-${status}`} />
)}
</Transition>
B、in----boolean( default:false )修改组件的state
C、enter----boolean( default:true)让组件具有过渡的功能
D、mountOnEnter----boolean( default:false )延迟加载children component
E、exit----boolean( default:true )然组件具有隐藏的功能
F、unmountOnExit-----boolean( default:false )当component完成exiting,让给component 不挂载
G、timeout-----type: number | { enter?: number, exit?: number }
//所有过渡状态的时间都一样
timeout={500}
//或者可以详细定义
timeout={{
enter: 300,
exit: 500,
}}
H、addEventListener-----function
addEndListener={(node, done) => {
// use the css transitionend event to mark the finish of a transition
node.addEventListener('transitionend', done, false);
}}
I、onEnter-----function,在entering之前调用的函数
type: Function(node: HtmlElement, isAppearing: bool) -> void
default: function noop() {}
J、onEntering-----function,在状态为entering之后调用的函数
type: Function(node: HtmlElement, isAppearing: bool)
default: function noop() {}
K、onEntered-----function,在状态为entered之后调用的函数
ype: Function(node: HtmlElement, isAppearing: bool) -> void
default: function noop() {}
L、onExit-----function,在状态为exiting之前调用的函数
type: Function(node: HtmlElement) -> void
default: function noop() {}
M、onExiting-----function,在状态为exiting之后调用的函数
type: Function(node: HtmlElement) -> void
default: function noop() {}
N、onExited-----function,在状态为exited之后调用的函数
type: Function(node: HtmlElement) -> void
default: function noop() {}
2)<CSSTransition>组件-------属性跟<Transition>差不多
3)<TransitionGroup>组件-----可以管理一系列的<Transition>组件,<TransitionGroup>组件上面不定义任何animation,这全部定义在不同的<Transition>上面,同时可以结合<CSSTrabsition>使用
具有的属性pops
A、component---<TransitionGroup>组件默认最终渲染成的组件为<div>
type: any
default: 'div'
B、children---在<TransitionGroup>组件中的子组件的类型可以是任何类型
C、appear---控制该组件的子组件的所有animations,type:boolean
D、enter---控制该组件的子组件的所有enter时的animations,type:boolean
E、exit---控制该组件的子组件的所有exit时的animations,type:boolean
F、childFactory---控制该组件的子组件的所有exit时的animations,type:boolean
转载地址:
https://reactjs.org/docs/hooks-intro.html
https://reactcommunity.org/react-transition-group/transition