انتقال 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 از کامپوننت مادر به فرزند و همچنین برعکس را درک کرده باشید. همچنین می‌توانید کد کامل این مقاله را در صفحه گیت‌هاب آن پیدا کنید.

منبع

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

تفاوت‌های اصلی میان ReactJS و React-Native چه هستند؟

React Native به مدت دو سال در صحنه حضور داشته است، و از آنجایی که می‌تواند برای اندروید استفاده شود و ما را قادر سازد تا برنامه‌های موبایل میان پلتفرم...

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

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

المان‌های اصلی برای ساخت وبسایت‌های آژانس طراحی

امروز قصد دارم نکات مهمی در رابطه با چگونگی ساخت بهترین لایه‌بندی وبسایت برای شرکت طراحی‌تان را بگویم. آزمایشگاه‌ها و آژانس‌های طراحی یا اینکه با یکسر...

6 صفحه «About» برای الهام گرفتن

صفحه درباره ما یا About همواره یکی از صفحات بسیار مهم برای تجارت‌ها و صفحات نمونه کار مختلف است. در این پست قصد داریم شما را با ۶ صفحه درباره ما عالی...