সেটস্টেট আপডেট শেষ হয়ে যাওয়ার পরে আমি কোনও ফাংশন সম্পাদন করতে পারি?


174

আমি জেএসকে প্রতিক্রিয়া জানাতে খুব নতুন (যেমন, আজই শুরু হয়েছে)। সেটস্টেট কীভাবে কাজ করে তা আমি পুরোপুরি বুঝতে পারি না। আমি ব্যবহারকারী ইনপুটের উপর ভিত্তি করে গ্রিড আঁকার জন্য প্রতিক্রিয়া এবং ইজেল জেএসকে একত্রিত করছি। এখানে আমার জেএস বিন: http://jsbin.com/zatula/edit?js , আউটপুট

কোডটি এখানে:

        var stage;

    var Grid = React.createClass({
        getInitialState: function() {
            return {
                rows: 10,
                cols: 10
            }
        },
        componentDidMount: function () {
            this.drawGrid();
        },
        drawGrid: function() {
            stage = new createjs.Stage("canvas");
            var rectangles = [];
            var rectangle;
            //Rows
            for (var x = 0; x < this.state.rows; x++)
            {
                // Columns
                for (var y = 0; y < this.state.cols; y++)
                {
                    var color = "Green";
                    rectangle = new createjs.Shape();
                    rectangle.graphics.beginFill(color);
                    rectangle.graphics.drawRect(0, 0, 32, 44);
                    rectangle.x = x * 33;
                    rectangle.y = y * 45;

                    stage.addChild(rectangle);

                    var id = rectangle.x + "_" + rectangle.y;
                    rectangles[id] = rectangle;
                }
            }
            stage.update();
        },
        updateNumRows: function(event) {
            this.setState({ rows: event.target.value });
            this.drawGrid();
        },
        updateNumCols: function(event) {
            this.setState({ cols: event.target.value });
            this.drawGrid();
        },
        render: function() {
            return (
                <div>
                    <div className="canvas-wrapper">
                        <canvas id="canvas" width="400" height="500"></canvas>
                        <p>Rows: { this.state.rows }</p>
                        <p>Columns: {this.state.cols }</p>
                    </div>
                    <div className="array-form">
                        <form>
                            <label>Number of Rows</label>
                            <select id="numRows" value={this.state.rows} onChange={ this.updateNumRows }>
                                <option value="1">1</option>
                                <option value="2">2</option>
                                <option value ="5">5</option>
                                <option value="10">10</option>
                                <option value="12">12</option>
                                <option value="15">15</option>
                                <option value="20">20</option>
                            </select>
                            <label>Number of Columns</label>
                            <select id="numCols" value={this.state.cols} onChange={ this.updateNumCols }>
                                <option value="1">1</option>
                                <option value="2">2</option>
                                <option value="5">5</option>
                                <option value="10">10</option>
                                <option value="12">12</option>
                                <option value="15">15</option>
                                <option value="20">20</option>
                            </select>
                        </form>
                    </div>    
                </div>
            );
        }
    });
    ReactDOM.render(
        <Grid />,
        document.getElementById("container")
    );

আপনি জেএস বিনে দেখতে পাবেন যখন আপনি একটি ড্রপডাউনগুলির সাথে সারি বা কলামগুলির সংখ্যা পরিবর্তন করবেন, প্রথমবার কিছুই হবে না। পরের বার আপনি যখন একটি ড্রপডাউন মান পরিবর্তন করবেন, গ্রিডটি পূর্বের রাজ্যের সারি এবং কলাম মানগুলিতে আঁকবে। আমি অনুমান করছি যে এটি ঘটছে কারণ আমার এই.ড্রেগ্রিগ্রিড () ফাংশনটি সেটস্টেটটি সম্পূর্ণ হওয়ার আগেই সম্পাদন করছে। অন্য কোনও কারণ থাকতে পারে?

আপনার সময় এবং সাহায্যের জন্য ধন্যবাদ!

উত্তর:


449

setState(updater[, callback]) একটি অ্যাসিঙ্ক ফাংশন:

https://facebook.github.io/react/docs/react-component.html#setstate

সেট স্টেটটি দ্বিতীয় প্যারামের callbackমতো ব্যবহার শেষ করে আপনি কোনও ফাংশন সম্পাদন করতে পারেন:

this.setState({
    someState: obj
}, () => {
    this.afterSetStateFinished();
});

32
বা কেবল এই.সেটস্টেট ({কিছু স্টেট: আপত্তি}, এই.ফর্টসেট স্টেটফিনিশড);
আলেক্সি প্রকোপভ

আমি আমার নির্দিষ্ট উদাহরণটিতে এটি যুক্ত করতে চাই, @ ক্যানডায়্যু প্রস্তাবিত মত আমি কল this.drawGrid()করতে componentDidUpdateচাই, কারণ যে কোনও সময় setStateশেষ হয়ে গেলে , আমি গ্রিডটি পুনরায় আঁকতে চাইব (সুতরাং এটি কোডের কয়েকটি লাইন সংরক্ষণ করবে), তবে একই জিনিসটি সম্পাদন করব ।
monalisa717

দুর্দান্ত উত্তর ... আমাকে অনেক সাহায্য করেছে
মোহাম্মাদ রেজা দেহগনি

এটি আমার জন্য অনেক সময় সাশ্রয় করে। ধন্যবাদ।
নয়ন দে

28

renderপরিবর্তনগুলি উপস্থিত থাকলে আপনাকে প্রতিবার setStateউপাদানটি পুনরায় রেন্ডার করতে ডাকা হবে । আপনি যদি drawGridআপনার update*পদ্ধতিগুলিতে কল করার পরিবর্তে আপনার কলটি সেখানে স্থানান্তরিত করেন তবে আপনার কোনও সমস্যা হবে না।

যদি এটি আপনার পক্ষে কাজ করে না, তবে সেখানে একটি ওভারলোড রয়েছে setStateযা দ্বিতীয় প্যারামিটার হিসাবে কলব্যাক নেয়। আপনি সর্বশেষ উপায় হিসাবে এর সুবিধা নিতে সক্ষম হওয়া উচিত।


2
আপনাকে ধন্যবাদ - আপনার প্রথম পরামর্শটি কার্যকর হয় এবং (বেশিরভাগ ক্ষেত্রে) তা বোঝায়। আমি এটি করেছি: render: function() { this.drawGrid(); return......
monalisa717

3
আহেম, দয়া করে এটি করবেন না render()... সিটলকের উত্তরটি গ্রহণযোগ্য হওয়া উচিত
মফেইনিস

এটি একটি ভুল উত্তর, সেটস্টেট ইনফিনিটি লুপের জন্য যাবে এবং পৃষ্ঠাটি ক্র্যাশ করবে।
ম্যাভারিক

জাস্টিন, আমি কেন আগ্রহী যে কেন কলব্যাকটি setStateএকটি শেষ অবলম্বন হিসাবে ব্যবহার করা উচিত সে সম্পর্কে আমি আগ্রহী I আমি এখানকার বেশিরভাগ লোকের সাথে একমত যে এই পদ্ধতির ব্যবহারটি বোধগম্য।
মনালিসা 717

1
@ রোহমের এটি প্রতিটি রেন্ডারে কল কার্যকর করার জন্য ব্যয়বহুল উপায়, যদিও এটি অবশ্যই প্রতিটি কলে প্রয়োজন হয় না। যদি এটি খাঁটি reactহয়ে থাকে তবে বেশিরভাগ ক্ষেত্রে ভোম খুব বেশি কাজ না করার বিষয়ে খেয়াল রাখে, এটি আপনি যে কোনও লাইব্রেরি হ্রাস করতে চান তার সাথে
বিরতি দেওয়া হয়েছে

14

মেকিং setStateরিটার্ন একটিPromise

একটি ক্ষণস্থায়ী ছাড়াও callbackকরার setState()পদ্ধতি, আপনি এটি একটি চারপাশে মোড়ানো করতে asyncফাংশন এবং ব্যবহার then()পদ্ধতি - যা কিছু ক্ষেত্রে একটি ক্লিনার কোড উত্পাদন করতে পারেন:

(async () => new Promise(resolve => this.setState({dummy: true}), resolve)()
    .then(() => { console.log('state:', this.state) });

এবং এখানে আপনি আরও এক ধাপ এগিয়ে নিতে পারেন এবং একটি পুনরায় ব্যবহারযোগ্য setStateফাংশন করতে পারেন যা আমার মতে উপরের সংস্করণটির চেয়ে ভাল:

const promiseState = async state =>
    new Promise(resolve => this.setState(state, resolve));

promiseState({...})
    .then(() => promiseState({...})
    .then(() => {
        ...  // other code
        return promiseState({...});
    })
    .then(() => {...});

এটি প্রতিক্রিয়া 16.4 এ দুর্দান্ত কাজ করে , তবে আমি এখনও প্রতিক্রিয়াটির পূর্ববর্তী সংস্করণগুলিতে এটি পরীক্ষা করে দেখিনি ।

এছাড়াও উল্লেখ করার মতো যে আপনার কলব্যাক কোডটি componentDidUpdateপদ্ধতিতে রাখা বেশিরভাগ ক্ষেত্রে - সম্ভবত সমস্ত ক্ষেত্রেই একটি ভাল অনুশীলন।


11

যখন নতুন প্রপস বা রাজ্যগুলি প্রাপ্ত হচ্ছে (যেমন আপনি setStateএখানে কল করেন), প্রতিক্রিয়া কিছু ফাংশন শুরু করে, যা ডাকা হয় componentWillUpdateএবংcomponentDidUpdate

আপনার ক্ষেত্রে, componentDidUpdateকল করার জন্য কেবল একটি ফাংশন যুক্ত করুনthis.drawGrid()

এখানে জেএস বিন মধ্যে কোড কাজ করছে

আমি কোড হিসাবে উল্লিখিত হিসাবে, componentDidUpdateপরে অনুরোধ করা হবেthis.setState(...)

তারপর componentDidUpdateভিতরে কল করতে যাচ্ছেthis.drawGrid()

প্রতিক্রিয়া লাইফসাইক্যাল সম্পর্কে আরও পড়ুন https://facebook.github.io/react/docs/comp घटक- specs.html # updating -comp घटक willupdate


পরিবর্তে কেবল লিঙ্কটি আটকানো। দয়া করে উত্তরে প্রাসঙ্গিক অংশ যুক্ত করুন।
ফিনিক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.