আমার একটি ফাংশন উপাদান রয়েছে এবং আমি এটি পুনরায় রেন্ডার করতে বাধ্য করতে চাই।
আমি কীভাবে এটি করতে পারি?
যেহেতু কোনও উদাহরণ নেই this, তাই আমি কল করতে পারি না this.forceUpdate()।
আমার একটি ফাংশন উপাদান রয়েছে এবং আমি এটি পুনরায় রেন্ডার করতে বাধ্য করতে চাই।
আমি কীভাবে এটি করতে পারি?
যেহেতু কোনও উদাহরণ নেই this, তাই আমি কল করতে পারি না this.forceUpdate()।
উত্তর:
প্রতিক্রিয়া হুক ব্যবহার করে, আপনি এখন useState()আপনার ফাংশন উপাদান কল করতে পারেন ।
useState() 2 টি জিনিসের একটি অ্যারে ফিরিয়ে দেবে:
সেটারের দ্বারা মান আপডেট করা আপনার ফাংশন উপাদানটিকে পুনরায় রেন্ডার করতে বাধ্য করবে ,
ঠিক যেমন forceUpdate:
import React, { useState } from 'react';
//create your forceUpdate hook
function useForceUpdate(){
const [value, setValue] = useState(0); // integer state
return () => setValue(value => value + 1); // update the state to force render
}
function MyComponent() {
// call your hook here
const forceUpdate = useForceUpdate();
return (
<div>
{/*Clicking on the button will force to re-render like force update does */}
<button onClick={forceUpdate}>
Click to re-render
</button>
</div>
);
}
আপনি এখানে একটি ডেমো খুঁজে পেতে পারেন ।
উপরের উপাদানটি একটি কাস্টম হুক ফাংশন ( useForceUpdate) ব্যবহার করে যা প্রতিক্রিয়ার স্টেট হুক ব্যবহার করে useState। এটি উপাদানটির রাষ্ট্রের মান বাড়ায় এবং এভাবে উপাদানটিকে পুনরায় সরবরাহ করতে প্রতিক্রিয়া জানায়।
এই উত্তরের একটি পুরানো সংস্করণে স্নিপেট একটি বুলিয়ান মান ব্যবহার করেছে এবং এটিকে টগল করে forceUpdate()। এখন আমি আমার উত্তরটি সম্পাদনা করেছি, স্নিপেট একটি বুলিয়ান পরিবর্তে একটি সংখ্যা ব্যবহার করে।
কেন? (আপনি আমাকে জিজ্ঞাসা করবে)
কারণ একবার যখন আমার সাথে ঘটেছিল যে আমার forceUpdate()পরে 2 টি পৃথক ঘটনা থেকে দু'বার কল করা হয়েছিল, এবং এভাবে এটি তার মূল অবস্থানে বুলিয়ান মানটির পুনরায় গবেষণা করছিল, এবং উপাদানটি কখনও রেন্ডার হয়নি।
এর কারণ এটির useStateসেটারে ( setValueএখানে) Reactপূর্বের রাজ্যটিকে নতুনের সাথে তুলনা করুন, এবং রাজ্যটি আলাদা হলেই রেন্ডার করুন।
forceUpdate।
useStateহুক সম্পর্কে কথা বলছি , শ্রেণি নয় ' setStateযা প্রকৃতপক্ষে তুলনা করে না (যদি না আপনি উক্ত আপডেট পদ্ধতিটি প্রয়োগ করেন)। আমি পোস্ট করা একই ডেমোটি দেখুন, তবে এর জন্য ব্যবহৃত একটি স্ট্যাটিক মান সহ setState, এটি আবার রেন্ডার হয় না: কোডস্যান্ডবক্স.আইও
আপডেট প্রতিক্রিয়া v16.8 (16 ফেব্রুয়ারী 2019 রিলিজ)
যেহেতু হুক সহ 16.8 প্রকাশিত হয়েছে প্রতিক্রিয়া , ফাংশন উপাদানগুলিতে এখন অধ্যবসায়ী ধরে রাখার ক্ষমতা রয়েছে state। সেই দক্ষতার সাহায্যে আপনি এখন একটি অনুকরণ করতে পারেন forceUpdate:
মনে রাখবেন যে এই পদ্ধতির পুনর্বিবেচনা করা উচিত এবং বেশিরভাগ ক্ষেত্রে যখন আপনাকে কোনও আপডেট চাপিয়ে দেওয়ার দরকার হয় আপনি সম্ভবত কিছু ভুল করছেন।
16.8.0 প্রতিক্রিয়া আগে
না আপনি পারবেন না, স্টেট-লেস ফাংশন উপাদানগুলি কেবল স্বাভাবিক functionsযা প্রত্যাবর্তন করে jsx, আপনি লাইফ চক্র পদ্ধতিগুলি থেকে কোনওরকম অ্যাক্সেস পাবেন না কারণ আপনি এর থেকে প্রসারিত করছেন না React.Component।
renderশ্রেণীর উপাদানগুলির পদ্ধতি অংশ হিসাবে ফাংশন-উপাদানটি ভাবেন ।
propsবা stateপরিবর্তন হয় না। স্টেটলেস উপাদানগুলিতে কোনও ফাংশন না থাকায় আপনি রেন্ডার ফাংশনটিকে জোর করতে পারবেন নাrender । আড়ম্বরহীন উপাদান নেই extends React.Componentতারা যে আয় শুধু সাধারণ ফাংশন হয় jsx।
অফিসিয়াল প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী ( https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate ) এখন এই ভাবে আপনি বিশেষ পরামর্শ দেওয়া হচ্ছে সত্যিই এটা করতে প্রয়োজন:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
const [, forceUpdate] = useReducer(x => x + 1, 0);
আমার প্রতিক্রিয়াশীল কার্যকরী উপাদানগুলি রেন্ডার করার জন্য আমি তৃতীয় পক্ষের লাইব্রেরিটি ব্যবহার-বল-আপডেট বলে ব্যবহার করি। মোহন মত কাজ। আপনার প্রকল্পে প্যাকেজটি আমদানি করুন এবং এটি ব্যবহার করুন।
import useForceUpdate from 'use-force-update';
const MyButton = () => {
const forceUpdate = useForceUpdate();
const handleClick = () => {
alert('I will re-render now.');
forceUpdate();
};
return <button onClick={handleClick} />;
};
useForceUpdateব্যবহার করে useCallback। এই লিবিবটি আপনাকে কয়েকটি কীস্ট্রোক সংরক্ষণ করতে কেবল একটি ইউটিলিটি লাইব।
দাবি অস্বীকার: সমস্যাটির উত্তর নেই।
একটি গুরুত্বপূর্ণ নোট এখানে রেখে:
আপনি যদি রাষ্ট্রবিহীন উপাদানকে জোর করে আপডেট করার চেষ্টা করছেন, আপনার নকশায় কিছু ভুল হওয়ার সম্ভাবনা রয়েছে।
নিম্নলিখিত বিষয়গুলি বিবেচনা করুন:
হুকগুলি স্পষ্টভাবে ব্যবহার না করেই করা যেতে পারে তবে শর্ত থাকে যে আপনি নিজের উপাদান এবং একটি রাজ্যকে রাজ্যহীন উপাদানটির পিতামাতাদের সাথে যুক্ত করে:
const ParentComponent = props => {
const [updateNow, setUpdateNow] = useState(true)
const updateFunc = () => {
setUpdateNow(!updateNow)
}
const MyComponent = props => {
return (<div> .... </div>)
}
const MyButtonComponent = props => {
return (<div> <input type="button" onClick={props.updateFunc} />.... </div>)
}
return (
<div>
<MyComponent updateMe={updateNow} />
<MyButtonComponent updateFunc={updateFunc}/>
</div>
)
}
গৃহীত উত্তর ভাল। এটি বুঝতে সহজ করে তুলতে।
উদাহরণ উপাদান:
export default function MyComponent(props) {
const [updateView, setUpdateView] = useState(0);
return (
<>
<span style={{ display: "none" }}>{updateView}</span>
</>
);
}
পুনরায় রেন্ডারিং করার জন্য নীচের কোডটিতে কল করুন:
setUpdateView((updateView) => ++updateView);
এর keyকোনওটিই আমাকে সন্তোষজনক উত্তর দেয় নি তাই শেষ পর্যন্ত আমি যা চেয়েছিলাম তা পেয়েছিলাম প্রোপ, ইউজারিফ এবং কিছু এলোমেলো আইডি জেনারেটরের মতো shortid।
মূলত, আমি কিছু চ্যাট অ্যাপ্লিকেশনটি চেয়েছিলাম যখন প্রথমবার কেউ অ্যাপ্লিকেশনটি খোলার সময় নিজেই খেলতে পারে। সুতরাং, অ্যাসিঙ্কের অপেক্ষার সহজতার সাথে উত্তরগুলি কখন এবং কী আপডেট হবে তা সম্পর্কে আমার সম্পূর্ণ নিয়ন্ত্রণ প্রয়োজন।
উদাহরণ কোড:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// ... your JSX functional component, import shortid somewhere
const [render, rerender] = useState(shortid.generate())
const messageList = useRef([
new Message({id: 1, message: "Hi, let's get started!"})
])
useEffect(()=>{
await sleep(500)
messageList.current.push(new Message({id: 1, message: "What's your name?"}))
// ... more stuff
// now trigger the update
rerender(shortid.generate())
}, [])
// only the component with the right render key will update itself, the others will stay as is and won't rerender.
return <div key={render}>{messageList.current}</div>
আসলে এটি আমাকে রোলিংয়ের সাথে চ্যাট বার্তার মতো কিছু রোল করার অনুমতিও দেয়।
const waitChat = async (ms) => {
let text = "."
for (let i = 0; i < ms; i += 200) {
if (messageList.current[messageList.current.length - 1].id === 100) {
messageList.current = messageList.current.filter(({id}) => id !== 100)
}
messageList.current.push(new Message({
id: 100,
message: text
}))
if (text.length === 3) {
text = "."
} else {
text += "."
}
rerender(shortid.generate())
await sleep(200)
}
if (messageList.current[messageList.current.length - 1].id === 100) {
messageList.current = messageList.current.filter(({id}) => id !== 100)
}
}