انتقال state میان کامپوننت ها در reactjs

گردآوری و تالیف : عرفان کاکایی
تاریخ انتشار : 18 مرداد 1397
دسته بندی ها : جاوا اسکریپت

در این پست، نحوه انتقال state بین کامپوننت‌های مختلف در React.js را توضیح خواهم داد. ما برنامه ساده‌ای به نام «چند کتاب خواندید؟» می‌سازیم. در اینجا، دو کامپوننت داریم. یک کامپوننت بزرگ به نام «کتابخانه» و یک کامپوننت کوچک‌تر به نام «کتاب». در state کتابخانه، ۳ کتاب داریم و هر کتاب، state خود را دارد.

حال بیایید کدنویسی را شروع کنیم.

انتقال state از کامپوننت مادر به کامپوننت فرزند

در کامپوننت کتابخانه خود، این state را داریم:

this.state = {
    reads: 0,
    books: [
        {
            name: 'Zero to one',
            isbn: '9780804139298',
            author: 'Peter Thiel',
            cover: 'https://images.gr-assets.com/books/1414347376l/18050143.jpg',
            status: false
        },
        {
            name: "The Manager's Path",
            isbn: '9781491973899',
            author: 'Camille Fournier',
            cover: 'https://images.gr-assets.com/books/1484107737l/33369254.jpg',
            status: false
        },
        {
            name: 'Calculus, Better Explained',
            isbn: '9781470070700',
            author: 'Kalid Azad',
            cover: 'https://images.gr-assets.com/books/1448590460l/27993945.jpg',
            status: false
        }
    ]
};

ما می‌خواهیم this.state.books.length را به عنوان یک عدد بسازیم. هر کدام از کامپوننت‌های کتاب، ویژگی‌هایی از آرایه کتاب، موجود در کامپوننت کتابخانه را دارند. باید به هر دوی این کامپوننت‌ها رسیدگی کنیم.

در ابتدا، با کامپوننت مادر شروع می‌کنیم. ما باید کامپوننت کتاب را بسازیم و مقادیر مختلف خود را به این صورت به آن منتقل کنیم:

{
    this.state.books.map((_book, _id) => {
        return (
            <Book
                handleCounter={this.handleCounter}
                key={_id}
                id={_book.isbn}
                name={_book.name}
                isbn={_book.isbn}
                author={_book.author}
                cover={_book.cover}
            />
        );
    });
}

نکته: handleConter را فعلا نادیده بگیرید.

سپس به کامپوننت فرزند، یعنی کتاب می‌رسیم. ما مقادیر را از کامپوننت مادر گرفته‌ایم؛ حال بیایید از آن‌ها استفاده کنیم:

...
render() {
    return (
        <Card>
            <Image
                src={this.props.cover}
                alt="Book cover"
...

تا به اینجا، سه کامپوننت کتاب از کامپوننت مادر، یعنی کتابخانه ساخته‌ایم، و مقادیر آن‌ها را بر پایه state مادر تعیین کرده‌ایم. حال بیایید به بخش دوم برویم.

انتقال state از کامپوننت فرزند به کامپوننت مادر

در این بخش، می‌خواهیم تعداد کتاب‌های خوانده شده را با بررسی هر چک‌باکس کتاب مدیریت کنیم. در کامپوننت کتاب، این state را داریم:

this.state = {
    status: false,
    id: this.props.id
};

نکته : انتقال ویژگی‌های به کامپوننت را فراموش نکنید.

Status به معنای خواندن، یا نخواندن یک کتاب است، مقدار پیشفرض آن false، و آی‌دی آن، همان آی‌دی کتاب است.

باید در هنگام بروزرسانی state مادر، تغییرات این state را نیز مدیریت کنیم.

در کامپوننت کتاب، یک چک‌باکس اضافه می‌کنیم که تغییر وضعیت کتاب را دریافت می‌کند، و به این صورت this.handleChange را به رویداد onChange منتقل می‌کند:

<input type="checkbox" name="example" onChange={this.handleChange} />

باید در ابتدا، تابع مربوطه را متصل کنیم، سپس state کتاب را به وضعیت جدید بروزرسانی کنیم، و پس از بروزرسانی state فرزند، state مادر را نیز به این صورت بروزرسانی می‌کنیم:

handleChange() {
        this.setState({status: !this.state.status}, this.updateLibraryCount);
    }

updateLibraryCount() {
        this.props.handleCounter(this.state);
    }

در updateLibraryCount، باید تابع handleCounter موجود در کتابخانه را به عنوان یک ویژگی استفاده کنیم، state کتاب را به آن منتقل کنیم، و حالا کامپوننت کتابخانه می‌تواند state کتاب را ببیند.

handleCounter(_State) {
        //با جستجو آی‌دی خاص این کتاب، ورودی آن را پیدا کن
        const ObjNum = this.state.books.findIndex(
            _book => _book.isbn === _State.id
        );

        //سپس مقدار آن را در کامپوننت کتاباخانه بروزرسانی کن
        this.setState(
            {
                books: update(
                    ObjNum,
                    {...this.state.books[ObjNum], status: _State.status},
                    this.state.books
                )
            },
            () => {
                const _read = this.state.books.filter(_book => _book.status === true)
                    .length;
                this.setState({reads: _read});
            }
        );
    }

کار ما در اینجا به پایان می‌رسد. امیدوارم نحوه انتقال state از کامپوننت مادر به فرزند و همچنین برعکس را درک کرده باشید. همچنین می‌توانید کد کامل این مقاله را در صفحه گیت‌هاب آن پیدا کنید.

منبع

این مطلب را با دیگران به اشتراک بگذارید :

مقالات پیشنهادی

55 نمونه کامل که نشان دهنده الهام گرفتن از همه چیزه

مردم همیشه میگن پیدا کردن چیزی الهام بخش برای خلق یک چیز خلاقانه خیلی سخته . من میگم همیشه باید سعی کنیم چیز های متفاوت رو احساس کنیم . بعضی ها حتی به...

شش طرح زیبا و الهام بخش از codepen

امروز میخوام چند طرح زیبا از codepen رو بهتون نشون بدم که کار آقای Karim Maaloul . کارهای ایشون با ابزار های مختلفی انجام شده و بسیار بسیار عالی و ز...

25 وبسایت الهام بخش با استفاده از پارالاکس

parallax scrolling هنوز در کشور ما بخوبی جا نیوفتاده و مخاطب های خودشو به طور کامل بدست نیاورده اما در وب سایت های غیر ایرانی به وفور از این تکنیک است...

وب سایت های الهام بخش برای طراحی

امروز قصد داریم یک سری وبسایت های خارجی که بطور کاربردی ، زیبا و قدرتمند طراحی شدن رو براتون قرار بدیم تا شما بتونین با طریقه طراحی اونها آشنا بشین یا...