bir React işlevi / Hooks bileşenindeki componentDidMount eşdeğeri?


99

componentDidMountReact fonksiyonel bileşenlerini kancalar aracılığıyla simüle etmenin yolları var mı?

Yanıtlar:


199

Kancaların kararlı sürümü için (React Sürümü 16.8.0+)

İçin componentDidMount

useEffect(() => {
  // Your code here
}, []);

İçin componentDidUpdate

useEffect(() => {
  // Your code here
}, [yourDependency]);

İçin componentWillUnmount

useEffect(() => {
  // componentWillUnmount
  return () => {
     // Your code here
  }
}, [yourDependency]);

Yani bu durumda, bağımlılığınızı bu diziye aktarmanız gerekir. Böyle bir durumunuz olduğunu varsayalım

const [count, setCount] = useState(0);

Ve sayım arttığında, işlev bileşeninizi yeniden oluşturmak istersiniz. O zaman useEffectböyle görünmelisin

useEffect(() => {
  // <div>{count}</div>
}, [count]);

Bu şekilde, sayınız her güncellendiğinde, bileşeniniz yeniden işlenir. Umarım bu biraz yardımcı olur.


Kapsamlı açıklama! ComponentDidReceiveProps'ı simüle etmenin bir yolu var mı?
jeyko

1
Var olsa bile farkında değilim. Tho github.com/facebook/react/issues/3279
Mertcan Diken

1
İkinci tartışmanın farkında olmadığım için bunun için teşekkür ederim useState. Bunu okuyan herkese, lütfen ikinci argümanı terk etmenin undefinedetkinizin her renderda tetiklenmesine neden olacağını unutmayın (yanılmıyorsam).
dimiguel

UseEffect'in bağımlılıklarını mı kastediyorsunuz (bir bağımlılık dizisi geçirme)? Eğer öyleyse evet, boş bırakırsanız, bu kodda bir hatadır. Dizi bozulması için, her ikisine de ihtiyacınız vardır [count, setCount], çünkü bu örnekte count sizin durum değişkeniniz ve setCount bu durumu güncellemek için işlevinizdir.
Mertcan Diken

Cevap için teşekkürler. Bununla ilgili belgeler burada reactjs.org/docs/hooks-effect.html
Josh

3

Kabul edilen cevap işe yarasa da tavsiye edilmez. Birden fazla durumunuz olduğunda ve bunu useEffect ile kullandığınızda, bağımlılık dizisine ekleme veya hiç kullanmama konusunda size uyarı verecektir.

Bazen size tahmin edilemeyen çıktılar verebilecek soruna neden olur. Bu nedenle, sınıf olarak işlevinizi yeniden yazmak için biraz çaba sarf etmenizi öneririm. Çok az değişiklik var ve bazı bileşenlere sınıf, bazılarına da işlev olarak sahip olabilirsiniz. Tek bir kural kullanmak zorunda değilsiniz.

Örneğin bunu al

function App() {
  const [appointments, setAppointments] = useState([]);
  const [aptId, setAptId] = useState(1);

  useEffect(() => {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = aptId;
          console.log(aptId);
          setAptId(aptId + 1);
          return item;
        })
        setAppointments(apts);
      });
  }, []);

  return(...);
}

ve

class App extends Component {
  constructor() {
    super();
    this.state = {
      appointments: [],
      aptId: 1,
    }
  }

  componentDidMount() {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = this.state.aptId;
          this.setState({aptId: this.state.aptId + 1});
          console.log(this.state.aptId);
          return item;
        });
        this.setState({appointments: apts});
      });
  }

  render(...);
}

Bu sadece örneğin . bu yüzden kodla ilgili en iyi uygulamalar veya olası sorunlar hakkında konuşmayalım. Bunların her ikisi de aynı mantığa sahiptir, ancak daha sonra beklendiği gibi çalışır. Bu kez useEffect çalışırken componentDidMount işlevini elde edebilirsiniz, ancak uygulamanız büyüdükçe bazı sorunlarla karşılaşma olasılığınız OLABİLİR. Dolayısıyla, bu aşamada yeniden yazmak yerine, bunu erken aşamada yapmak daha iyidir.

Ayrıca, OOP o kadar da kötü değil, Prosedüre Yönelik Programlama yeterli olsaydı, Nesne Yönelimli Programlamaya asla sahip olamazdık. Bazen acı verir, ancak daha iyidir (teknik olarak, kişisel sorunlar bir yana).


1
Bunu ben yaptım. Kanca kullanırken sorunla karşılaştım. Sorun, sınıfa dönüştürüldükten sonra ortadan kalktı.
Julez

2

componentDidMountİşlevsel bileşenler yoktur , ancak React Hook'lar, useEffectkancayı kullanarak davranışı taklit etmenin bir yolunu sağlar .

useEffect()Yalnızca bağlama sırasında geri aramayı çalıştırmak için ikinci bağımsız değişken olarak boş bir dizi iletin.

Lütfen üzerindeki belgeleriuseEffect okuyun .

function ComponentDidMount() {
  const [count, setCount] = React.useState(0);
  React.useEffect(() => {
    console.log('componentDidMount');
  }, []);

  return (
    <div>
      <p>componentDidMount: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <ComponentDidMount />
  </div>,
  document.querySelector("#app")
);
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>


0

Kullanmak istediğiniz useEffect()işlevi nasıl kullandığınıza bağlı olarak,) (sadece componentDidMount gibi hareket edebilir, hangi.

Örneğin. loadedbaşlangıçta false olarak ayarlanmış özel bir durum özelliğini kullanabilir ve işlemede bunu true olarak değiştirebilir ve efekti yalnızca bu değer değiştiğinde çalıştırabilirsiniz.

Dokümantasyon


1
Bu çözüm ideal değil. Sadece bileşenin bağlanıp bağlanmadığını belirlemek için bir durum değeri kullanmak kötü bir fikirdir. Ayrıca, bir özellik kullanacak olsaydınız, başka bir yeniden oluşturmayı tetiklemeyeceğinden bir ref daha iyi olurdu.
Yangshun Tay

0

componentDidMount () için tam eşdeğer kanca

useEffect(()=>{},[]);

umarım faydalı olur :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.