Saya mungkin melewatkan sesuatu yang sangat jelas dan ingin membersihkan diri.
Berikut pemahaman saya.
Dalam komponen reaksi naif, kita memiliki states
& props
. Memperbarui state
dengan setState
merender ulang seluruh komponen. props
kebanyakan hanya baca dan memperbaruinya tidak masuk akal.
Dalam komponen react yang berlangganan toko redux, melalui sesuatu seperti store.subscribe(render)
, itu jelas merender ulang setiap kali toko diperbarui.
react-redux memiliki helper connect()
yang menyuntikkan bagian dari pohon status (yang menarik bagi komponen) dan actionCreators props
ke komponen, biasanya melalui sesuatu seperti
const TodoListComponent = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
Tetapi dengan pemahaman bahwa a setState
sangat penting untuk TodoListComponent
bereaksi terhadap perubahan pohon status redux (render ulang), saya tidak dapat menemukan kode apa pun state
atau setState
terkait dalam TodoList
file komponen. Bunyinya seperti ini:
const TodoList = ({ todos, onTodoClick }) => (
<ul>
{todos.map(todo =>
<Todo
key={todo.id}
{...todo}
onClick={() => onTodoClick(todo.id)}
/>
)}
</ul>
)
Dapatkah seseorang mengarahkan saya ke arah yang benar tentang apa yang saya lewatkan?
PS Saya mengikuti contoh daftar rencana yang dibundel dengan paket redux .
sumber
prev.a === current.a && prev.b === current.b && .....
. Itu mengasumsikan bahwa setiap perubahan data akan menghasilkan referensi baru, yang berarti pembaruan data yang tidak dapat diubah diperlukan alih-alih mutasi langsung.Jawaban saya sedikit keluar dari bidang kiri. Ini menjelaskan masalah yang membawa saya ke posting ini. Dalam kasus saya, tampaknya aplikasi tersebut Tidak merender ulang, meskipun menerima alat peraga baru.
React devs memiliki jawaban untuk pertanyaan yang sering ditanyakan ini, sesuatu yang sesuai jika (store) dimutasi, 99% dari waktu itulah alasan react tidak akan dirender ulang. Namun tidak ada tentang 1% lainnya. Mutasi tidak terjadi di sini.
TLDR;
Tepi Kasus: Setelah
state
update, maka aplikasi tidak re-render!Ternyata jika aplikasi Anda hanya menggunakan
state
untuk menampilkan elemennya,props
dapat memperbarui, tetapistate
tidak mau, jadi tidak ada render ulang.Saya punya
state
yang tergantung pada yangprops
diterima dari reduxstore
. Data yang saya butuhkan belum ada di toko, jadi saya mengambilnyacomponentDidMount
sebagaimana mestinya. Saya mendapatkan propsnya kembali, ketika peredam saya memperbarui toko, karena komponen saya terhubung melalui mapStateToProps. Tetapi halaman tersebut tidak merender, dan statusnya masih penuh dengan string kosong.Contohnya adalah pengguna memuat halaman "edit posting" dari url yang disimpan. Anda memiliki akses ke
postId
dari url, tetapi infonya belum masukstore
, jadi Anda mengambilnya. Item di halaman Anda adalah komponen yang dikontrol - jadi semua data yang Anda tampilkan ada di dalamnyastate
.Menggunakan redux, data diambil, penyimpanan diperbarui, dan komponen
connect
diedit, tetapi aplikasi tidak mencerminkan perubahan. Dilihat lebih dekat,props
diterima, tetapi aplikasi tidak diperbarui.state
tidak diperbarui.Yah,
props
akan memperbarui dan menyebarkan, tetapistate
tidak. Anda perlu memberi tahu secara khususstate
untuk memperbarui.Anda tidak dapat melakukan ini
render()
, dancomponentDidMount
sudah menyelesaikan siklusnya.componentWillReceiveProps
adalah tempat Anda memperbaruistate
properti yang bergantung padaprop
nilai yang diubah .Contoh Penggunaan:
componentWillReceiveProps(nextProps){ if (this.props.post.category !== nextProps.post.category){ this.setState({ title: nextProps.post.title, body: nextProps.post.body, category: nextProps.post.category, }) } }
Saya harus berteriak ke artikel ini yang mencerahkan saya tentang solusi yang gagal disebutkan oleh puluhan postingan, blog, dan repo lain. Siapa pun yang kesulitan menemukan jawaban untuk masalah yang jelas tidak jelas ini, Ini dia:
Metode siklus hidup komponen ReactJs - Menyelami lebih dalam
sumber
React 16.3
seterusnya, Anda harus menggunakangetDerivedStateFromProps
bukancomponentWillReceiveProps
. Tetapi pada kenyataannya, Anda seharusnya tidak melakukan semua itu seperti yang diartikulasikan di siniJawaban ini merupakan ringkasan dari artikel Brian Vaughn yang berjudul You Probably Don't Need Derived State (07 Juni 2018).
Status berasal dari alat peraga adalah anti-pola dalam segala bentuknya. Termasuk menggunakan yang lebih lama
componentWillReceiveProps
dan yang lebih barugetDerivedStateFromProps
.Alih-alih mendapatkan status dari props, pertimbangkan solusi berikut.
Dua rekomendasi praktik terbaik
Rekomendasi 1. Komponen yang dikontrol sepenuhnya
Rekomendasi 2. Komponen yang sepenuhnya tidak terkontrol dengan kuncifunction EmailInput(props) { return <input onChange={props.onChange} value={props.email} />; }
// parent class class EmailInput extends Component { state = { email: this.props.defaultEmail }; handleChange = event => { this.setState({ email: event.target.value }); }; render() { return <input onChange={this.handleChange} value={this.state.email} />; } } // child instance <EmailInput defaultEmail={this.props.user.email} key={this.props.user.id} />
Dua alternatif jika, karena alasan apa pun, rekomendasi tersebut tidak berhasil untuk situasi Anda.
Alternatif 1: Atur ulang komponen yang tidak terkontrol dengan ID prop
Alternatif 2: Setel ulang komponen yang tidak terkontrol dengan metode instanceclass EmailInput extends Component { state = { email: this.props.defaultEmail, prevPropsUserID: this.props.userID }; static getDerivedStateFromProps(props, state) { // Any time the current user changes, // Reset any parts of state that are tied to that user. // In this simple example, that's just the email. if (props.userID !== state.prevPropsUserID) { return { prevPropsUserID: props.userID, email: props.defaultEmail }; } return null; } // ... }
class EmailInput extends Component { state = { email: this.props.defaultEmail }; resetEmailForNewUser(newEmail) { this.setState({ email: newEmail }); } // ... }
sumber
karena saya hanya tahu hal yang dilakukan redux, pada perubahan status toko memanggil componentWillRecieveProps jika komponen Anda bergantung pada status mutasi dan kemudian Anda harus memaksa komponen Anda untuk memperbaruinya seperti ini
Perubahan status 1-toko-2-panggilan (componentWillRecieveProps (() => {3-component state change}))
sumber