Yêu cầu thg 8 20, 2018 8:04 SA 148 0 2
  • 148 0 2
+1

Tại sao khi click lần đầu tiên hành động chưa thực thi ngay

Chia sẻ
  • 148 0 2

Mình đang tìm hiểu về ReactJs, mọi người cho mình hỏi tại sao đoạn code thực hiện chức năng Accordion dưới đây viết bằng ReactJs, khi load vào trang mình click lần đầu tiên thì sự kiện nó chưa kích hoạt ngay mà phải đến lần thứ 2 nó mới bắt sự kiện nhỉ:

https://codepen.io/anon/pen/NLKVrR?editors=1010

Mình cám ơn mọi nguwoif !

2 CÂU TRẢ LỜI


Đã trả lời thg 8 20, 2018 8:12 SA
Đã được chấp nhận
+4

Theo code hiện tại của bạn thì sau khi bạn click lần đầu tiên thì nó mới tiến hành gán sự kiện này vào thẻ div

itemAccor.onclick = () => itemAccor.classList.toggle("active");

Nếu bạn muốn nó chạy ngay lần đâu tiên thì nên khai báo phần gán function này ở trong hàm componentDidMount() luôn như này:

class Accordion extends React.Component {
    
  componentDidMount() {
    const myAccor = this.getEle.children;
    console.log(myAccor);
    for (let i = 0; i < myAccor.length; i++) {
      console.log(myAccor[i]);
      let itemAccor = myAccor[i];
      itemAccor.onclick = () => itemAccor.classList.toggle("active");
    }
  }
  
  render() {
    return (
      <div
        ref={ele => this.getEle = ele} 
        onClick={this.handleClick}>
        {this.props.children}
      </div>
    )
  }
}

class App extends React.Component {
  render() {
    return (
  
        <Accordion>
        
          <div className="accor">
            <div className="head">Head 1</div>
            <div className="body">
              Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            </div>
          </div>
        
          <div className="accor">
            <div className="head">Head 2</div>
            <div className="body">
              Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            </div>
          </div>
        
        </Accordion>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));
Chia sẻ
thg 8 20, 2018 8:27 SA

Bạn có thể cập nhât lại code như này sẽ tối ưu hơn tí 😄 https://codepen.io/anon/pen/NLKVwp?editors=1010

Avatar Hoang vn @wiliamfeng
thg 8 20, 2018 8:49 SA

@HuyDQ tks bạn nhé, code của bạn về logic dễ hiểu hơn rất nhiều

Đã trả lời thg 8 20, 2018 8:15 SA
+3

Bởi vì trong lần đầu tiên load, sau khi click vào thẻ div thì mới gán sự kiện onClick cho component Accor.

Chia sẻ
Avatar Hoang vn @wiliamfeng
thg 8 20, 2018 8:21 SA

LÀ như nào hả các bạn ? Mình chưa thực sự rõ lắm , các bạn có thể giải thích cho mình cặn kẽ hơn chút có đc không ? Mình thì hiểu thế này :

Thằng cha được khai báo sự kiện : onClick={this.handleClick} => khi click vô nó => nó sẽ gọi đến hàm handleClick => hàm này có chức năng duyệt qua các con nằm trong thằng cha => nếu phát hiện sự kiện click vừa rồi ứng với thằng con nào : itemAccor.onclick = () => itemAccor.classList.toggle("active") =,> sẽ toogle class cho thằng con đó.

Logic chẳng phải như vậy sao ?

thg 8 20, 2018 8:37 SA

@wiliamfeng hàm handleClick của bạn thực chất nó có nhiệm vụ gán cái sự kiện itemAccor.onclick = () => itemAccor.classList.toggle("active") cho thẻ div. Sau lần click đầu tiên thì các thẻ div đã được gán sự kiện rồi nó mới chạy được cái toggle bạn khai báo

Avatar Hoang vn @wiliamfeng
thg 8 20, 2018 8:43 SA

@HuyDQ tks bạn

thg 8 20, 2018 8:44 SA

@wiliamfeng ok bạn 😄

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí