React学习笔记

83 阅读4分钟

组件与Props

函数组件与class组件

接收: props 返回: react元素

    function Welcome(props) {
        return <h1> Hello, World </h1>;
    }

ES6语法:

class Welcome extends React.Component {
 render() {
     return <h1>Hello, {this.props.name}</h1>;
 }
 }

两者等价

渲染组件

DOM元素

const element = <div />

自定义元素

const elemet = <Welcom name="Sara" />

props

当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。

组件名称必须以大写字母开头

组合使用组件

这个App组件多次渲染了Welcome组件

class Welcome extends React.Component {
    render() {
        return <h1>Hello, {this.props.name}</h1>;
    }
}
const element = <Welcome name="Sara" />
function App() {
    return (
        <div>
            <Welcome name="Sara" />
            <Welcome name="Cahal" />
            <Welcome name="Edite" />
        </div>
    );
}
ReactDOM.render(
    <App />,
    document.getElementById('root')
)

提取组件

将复杂的,复用性较高的组件提取成为简单,易用的组件。 命名: 推荐从组件自身角度命名,而不是依赖于调用组件的上下文命名。

Props只读性

纯函数: 不修改函数入参的的函数。 React要求像纯函数一样保护Props(单向数据流)。

生命周期 && state

生命周期方法

截屏2022-01-05 下午5.46.15.png

state使用

注意事项:

不可以直接修改state

使用setState修改:

this.setState({commit: 'Hello'});

State的更新可能是异步的

这是因为this.statethis.props 的更新可能是异步的.所以最好不要依赖它来更新下一个状态。

/* not good*/
this.setState({
  counter: this.state.counter + this.props.increment,
});

解决方法: 通过回调函数来等待数据更新完成。

/** good */
this.setState((state, props) => ({ counter: state.counter + props.increment }));

State的更新会被合并

假如自定义了这个构造函数并且它拥有这些变量

constructor(props) {
    super(props);
    this.state = { posts: [], comments: [] };
}

可以分别更新state:

componentDidMount() {
    fetchPosts().then(response => {
        this.setState({
        // 单独更新
            posts: response.posts
        });
    });

    fettchComments().then(response => {
        this.setState({
        // 单独更新
            comments: response.comments
        })
    })
}

当更新posts时,state中的comments被保留,反之亦然。

State数据是独立且单向向下的

State是局部的,除了拥有并设置了它的组件,其他组件都无法访问。

<FormattedDate date={this.state.date} />

FormattedDate组件能接受date作为props,但是它不知道这个数据来自statestate只能影响本身及以下的组件

事件处理

·事件采用小驼峰命名法 ·使用JSX语法时需要传入一个函数作为事件处理函数,而不是字符串 ·必须显式使用e.preventDefault阻止默认行为

HTML: <button onClick="handleClick()"></button> React: // 用{}把方法名包裹起来 <button onClick="{handleClick}"></button>

HTML: <button onClick="console.log('click'); return false"></button> React:

function ActionLink() {
    function handleClick(e) {
    // 阻止
        e.preventDefault();
        console.log('click');
    }
    return (
        <a href="#" onClick={handleClick}>Click</a>
    )
}

添加事件处理函数时,应该将处理函数添加为该class的方法

注意: 需要在初始渲染组件的时候就添加监听

截屏2022-01-05 下午8.33.01.png

截屏2022-01-05 下午8.35.39.png

向事件处理函数传参时,通常使用两种方法:

· 箭头函数 · bind

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

箭头函数中,e必须显式传递(放在括号里)。

条件渲染

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
  return <UserGreeting />;  
  }
  return <GuestGreeting />;
  }
ReactDOM.render(
  // Try changing to isLoggedIn={true}:
  <Greeting isLoggedIn={false} />,  document.getElementById('root'));

使用isLoggedIn判断是否登录,通过return不同的组件来完成条件渲染。

阻止渲染: return null // 这样并不会影响生命周期函数执行。

key

在循环向组件插入值时,需要给该组件一个key用来作为每个组件的唯一标识,当然,这个标识应当也是唯一的。类似Vue中的for循环也是需要key

key 提取组件

key应该放在就近的数组上下文才有意义,假如你提取了一个组件,那么,key应该保留在组件上,而不是在组件里面。

兄弟节点里的key应当时唯一的

key会传递信息给React,但是不会传递进组件,所以如果组件内需要使用到key值,就需要换个名字传禁区

状态提升

当多个组件有共用数据时,可以将组件的state提升到父组件中去,这样就可以共享组件的状态,以及数据的单向向下传递。

组合

假如不知道传入的子组件的内容是什么,那么可以使用props.children属性来渲染这未知的组件

这里有一个组件(未知组件的父组件):

function Father(props) {
  return (
    <div className="author">
    // 内容将要渲染到这里
      {props.children}
    </div>
  )
}

这里是父组件渲染出来的内容组件

function Boreder(props) {
  return (
    <Father>
    // 这里是将要插入的子组件:
      <h1>good</h1>
      <p> you good</p>
    </Father>
  );
}

上面的Father组件内部的所有内容都将作为porps.children传到组件中去。

也可以不使用children:

function Mather(props) {
  return (
    <div>
      <div className="author">{props.son}</div>
      <div className="author">{props.doughter}</div>
    </div>
  );
}
function House(props) {
  return (
    <Mather son={<Sons />} doughter={<Dougther />} />
  );
}

哪些值不应该放入state

· 不是从props传来的 · 不会变化的 · 根据其他state或props传递/计算而来的

state的位置:

应该高于共同所有组件层级的位置