无法更新无状态子组件的道具

时间:2020-04-03 22:25:18

标签: javascript reactjs web-applications

我真的是React的新手,但是我试图做一个简单的注释applet。我的目标是通过单击“更改头像”按钮来更改每个用户的显示图片。 The Applet So Far

但是问题是我的按钮位于无状态的App组件中。实际上,除Avatar外,所有组件都是无状态的。单击“更改头像”仅能在控制台中更新appcounter的值:(有任何想法如何将这种counter道具推广到Avatar?这是完整的代码:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

let users = {
  1: {
    name: 'Harry',
    comment: 'Vengadium Leviosa!'
  },
  2: {
    name: 'Jason',
    comment: 'I don\'t believe in magic..'
  },
  3: {
    name: 'Copperfield',
    comment: 'Believe it ?'
  }
}

class Avatar extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: props.counter
    };
  }

  componentDidUpdate() {
    this.setState = {
      count: this.props.counter
    }
  }

  render() {
    return <img src={`https://robohash.org/${this.state.count}`} className='avatar' alt="User Avatar" />;
  }
}

function Comment(props) {
  return <p><b>{props.user.name}: </b>{props.user.comment}</p>;
}

function CommentBox(props) {
  return (
    <div className='comment-box'>
      <Avatar user={props.user} counter={props.counter} />
      <Comment user={props.user} />
    </div>
  );
}

function App() {

  let appcount = 0;
  function increment() {
    ++appcount;
    console.log('appcount:', appcount);
  };

  return (
    <div className='app'>
      <h2>Welcome to the Comments App</h2>
      {
        Object.entries(users).map(([key, value]) => {
          return <CommentBox user={value} counter={appcount + key} />
        })
      }
      <button onClick={increment}>Change Avatar</button>
    </div>
  );
}

ReactDOM.render(<App />,
  document.getElementById('root')
);

1 个答案:

答案 0 :(得分:2)

您应将appcount保持为App的状态,并将其传递给子组件。这就是导致CommentBox组件以及因此Avatar组件的重新呈现的原因。

import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

let users = {
  1: {
    name: 'Harry',
    comment: 'Vengadium Leviosa!'
  },
  2: {
    name: 'Jason',
    comment: 'I don\'t believe in magic..'
  },
  3: {
    name: 'Copperfield',
    comment: 'Believe it ?'
  }
}

function Avatar(props) {
  return (
      <img src={`https://robohash.org/${props.counter}`} className='avatar' alt="User Avatar" />
  );
}

function Comment(props) {
  return <p><b>{props.user.name}: </b>{props.user.comment}</p>;
}

function CommentBox(props) {
  return (
    <div className='comment-box'>
      <Avatar user={props.user} counter={props.counter} />
      <Comment user={props.user} />
    </div>
  );
}

function App() {
  const [appcount, setAppcount] = useState(0);

  function increment() {
    setAppcount(appcount + 1);
  };

  return (
    <div className='app'>
      <h2>Welcome to the Comments App</h2>
      {
        Object.entries(users).map(([key, value]) => {
          return <CommentBox user={value} counter={appcount + key} />
        })
      }
      <button onClick={increment}>Change Avatar</button>
    </div>
  );
}

ReactDOM.render(<App />,
  document.getElementById('root')
);