FAQ in react,react-transition-group

权兴为
2023-12-01

AJAX  AND  APIs

1、在React中如何调用AJAX?

使用AJAX库:AxiosjQuery 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

 类似资料: