uz
Feedback
ToCode

ToCode

Kanalga Telegramโ€™da oโ€˜tish

ื˜ื™ืคื™ื ืงืฆืจื™ื ืœืžืชื›ื ืชื™ื ืžืืช ื™ื ื•ืŸ ืคืจืง

Ko'proq ko'rsatish
1 419
Obunachilar
Ma'lumot yo'q24 soatlar
Ma'lumot yo'q7 kunlar
Ma'lumot yo'q30 kunlar
Postlar arxiv
ToCode
1 419
Untitled</a> by Ynon Perek (<a href="https://codepen.io/ynonp">@ynonp</a>) on <a href="https://codepen.io">CodePen</a>. </iframe>

ToCode
1 419
# ื˜ื™ืค JavaScript: ืฉืžื™ืจืช ืžื™ื“ืข ืœืงื‘ืฆื™ื ื•ื˜ืขื™ื ื” ื—ื–ืจื” ื™ื™ืฉื•ืžื™ Front End ืžืืคืฉืจื™ื ืœืžืฉืชืžืฉื™ื ืœื”ื›ื ื™ืก ืžื™ื“ืข. ื”ืจื‘ื” ืคืขืžื™ื ืื ื—ื ื• ืฉื•ืžืจื™ื ืืช ื”ืžื™ื“ืข ื‘ืฉืจืช ืื‘ืœ ืœืคืขืžื™ื ืื™ืŸ ืœื ื• ืฉืจืช ืื• ืฉื”ืžื™ื“ืข ืœื ืžืชืื™ื ืœืฉืžื™ืจื” ื‘ื‘ืกื™ืก ื”ื ืชื•ื ื™ื ื•ืื– ื”ื™ื™ื ื• ืจื•ืฆื™ื ืœืชืช ืืช ื”ืžื™ื“ืข ืœืžืฉืชืžืฉ ื‘ืชื•ืจ ืงื•ื‘ืฅ. ื‘ื“ื•ื’ืžื” ื–ื• ืืจืื” ืื™ืš ืœืžืžืฉ ื˜ื•ืคืก ืขื ืฉื ื™ ื›ืคืชื•ืจื™ื - ื›ืคืชื•ืจ ืื—ื“ "ืžื•ืจื™ื“" ืืช ื”ืžื™ื“ืข ืฉื‘ื˜ื•ืคืก ืœืงื•ื‘ืฅ JSON ืขืœ ืžื—ืฉื‘ ื”ืžืฉืชืžืฉ ื•ื›ืคืชื•ืจ ืฉื ื™ "ืžืขืœื”" ืงื•ื‘ืฅ JSON ืžื”ืžื—ืฉื‘ ื›ื“ื™ ืœืžืœื ืžืžื ื• ืืช ื”ื˜ื•ืคืก. ## ืงื•ื“ ื” HTML ืงื•ื“ ื” HTML ืฉืœ ื”ื“ื•ื’ืžื” ื›ื•ืœืœ ื˜ื•ืคืก ืขื 3 ืฉื“ื•ืช. ืœื›ืœ ืฉื“ื” ืžื•ื’ื“ืจ name ืฉื™ื”ื™ื” ื”ืžืคืชื— ื‘ JSON, ื•ื”ืขืจืš ื™ื”ื™ื” ื”ืขืจืš ืฉื”ืžืฉืชืžืฉ ื”ื›ื ื™ืก ืœืฉื“ื”. ื–ื” ื”ืงื•ื“:
<div>
  <button id="exportButton">Export to JSON</button>
  <button id="importButton">Import From JSON</button>
</div>
<hr />
<form>  
  <div>
  <label>Name: </label>
  <input type="text" name="name" />
  </div>
  
  <div>
    <label>Phone Number: </label>
    <input type="tel" name="tel" />
  </div>
  <div>
    <label>Email:</label>
    <input type="email" name="email" />
  </div>
</form>
## ืฉืžื™ืจืช ื”ืžื™ื“ืข ืœืงื•ื‘ืฅ ื‘ืฉื‘ื™ืœ ืœืงื—ืช ืืช ืชื•ื›ืŸ ื”ืฉื“ื•ืช ืœืงื•ื‘ืฅ ืืฆืœื™ ืขืœ ื”ืžื—ืฉื‘ ืื ื™ ืฆืจื™ืš ืฉื ื™ ื“ื‘ืจื™ื: ืงื•ื“ื ื›ืœ ืื ื™ ืฆืจื™ืš ืœื”ืขื‘ื™ืจ ืืช ื›ืœ ื”ืžื™ื“ืข ืžื”ื˜ื•ืคืก ืœืื•ื‘ื™ืงื˜ JSON, ื•ืื—ืจ ื›ืš ืฆืจื™ืš "ืœื”ื•ืจื™ื“" ืืช ืื•ื‘ื™ืงื˜ ื” JSON ื‘ืชื•ืจ ืงื•ื‘ืฅ. ื‘ืฉื‘ื™ืœ ื”ื—ืœืง ื”ืจืืฉื•ืŸ ืงืœ ืœื”ืฉืชืžืฉ ื‘ FormData:
const form = document.querySelector('form');
const fd = new FormData(form);
const data = JSON.stringify(Object.fromEntries(fd));
ืื—ืจื™ ื–ื” ืื ื™ ื™ื•ืฆืจ ืืœืžื ื˜ "ืงื™ืฉื•ืจ" ืฉื™ื•ืจื™ื“ ืืช ื”ืงื•ื‘ืฅ, ืœื•ื—ืฅ ืขืœื™ื• ื•ืžื•ื—ืง ืื•ืชื• ืžื”ืžืกืš:
const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(data);
const downloadAnchorNode = document.createElement('a');
downloadAnchorNode.setAttribute("href",     dataStr);
downloadAnchorNode.setAttribute("download", "form.json");
  document.body.appendChild(downloadAnchorNode); // required for firefox
downloadAnchorNode.click();
downloadAnchorNode.remove();
ืงื•ื“ ื”ืคื•ื ืงืฆื™ื” ื”ืžืœื ื”ื•ื ืœื›ืŸ:
function download() {
  const form = document.querySelector('form');
  const fd = new FormData(form);
  const data = JSON.stringify(Object.fromEntries(fd));

  const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(data);
  const downloadAnchorNode = document.createElement('a');
  downloadAnchorNode.setAttribute("href",     dataStr);
  downloadAnchorNode.setAttribute("download", "form.json");
  document.body.appendChild(downloadAnchorNode); // required for firefox
  downloadAnchorNode.click();
  downloadAnchorNode.remove();  
}
## ื”ืขืœืืช ื”ืงื•ื‘ืฅ ื•ืขื“ื›ื•ืŸ ื”ื˜ื•ืคืก ื”ื—ืœืง ื”ืฉื ื™ ื”ื•ื ืœืชืช ืœืžืฉืชืžืฉ ืืคืฉืจื•ืช ืœื”ืขืœื•ืช ืงื•ื‘ืฅ ื•ืœืขื“ื›ืŸ ืืช ื”ื˜ื•ืคืก ื‘ื”ืชืื ืœืคืจื˜ื™ื ืฉื‘ืงื•ื‘ืฅ. ืคื” ืื ื—ื ื• ื ืขืฉื” ืชื”ืœื™ืš ื”ืคื•ืš - ืงื•ื“ื ื ื™ืฆื•ืจ ืืœืžื ื˜ input ืฉืžื™ื•ืขื“ ืœื”ืขืœืืช ืงื‘ืฆื™ื, ื ืœื—ืฅ ืขืœื™ื• ื›ื“ื™ ืœืคืชื•ื— ืืช ื”ื“ื™ืืœื•ื’ ืฉืœ ื”ื“ืคื“ืคืŸ ืœื‘ื—ื™ืจืช ืงื•ื‘ืฅ, ื ืงืจื ืืช ืชื•ื›ืŸ ื”ืงื•ื‘ืฅ, ื ื”ืคื•ืš ืืช ื”ืชื•ื›ืŸ ืœ JSON ื•ืื– ื ืฉืชืžืฉ ื‘ืงื•ื“ JavaScript ื›ื“ื™ ืœืขื“ื›ืŸ ืืช ื”ืฉื“ื•ืช ืฉื‘ื˜ื•ืคืก ืžืชื•ืš ื”ืขืจื›ื™ื ืฉืงืจืื ื• ืžื” JSON. ืกืš ื”ื›ืœ ื”ืคื•ื ืงืฆื™ื” ื”ื™ื:
function upload() {
  const form = document.querySelector('form');
  const input = document.createElement('input');
  input.type = 'file';

  input.onchange = e => { 
    const file = e.target.files[0]; 

    const reader = new FileReader();
    reader.readAsText(file,'UTF-8');

    reader.onload = readerEvent => {
      const content = JSON.parse(readerEvent.target.result); // this is the content!
      console.log(typeof content);
      for (const key of Object.keys(content)) {
        console.log(key);
        form.querySelector(`input[name="${key}"]`).value = content[key];
      }
    }
  }

  input.click();
}
ื‘ืงื™ืฉื•ืจ ื”ื‘ื ืชื•ื›ืœื• ืœืžืฆื•ื ืืช ื›ืœ ื”ืงื•ื“ ื‘ืงื•ื“ืคืŸ ืขื•ื‘ื“: https://codepen.io/ynonp/pen/XWZbpoK ืื• ืื ืืชื ืงื•ืจืื™ื ืืช ื–ื” ืžื”ื“ืคื“ืคืŸ ืื– ื”ื ื” ื”ื•ื ื‘ื”ื˜ืžืขื”: <iframe height="300" style="width: 100%;" scrolling="no" title="Untitled" src="https://codepen.io/ynonp/embed/XWZbpoK?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen <a href="https://codepen.io/ynonp/pen/XWZbpoK">

ToCode
1 419
# ื—ืฆื™ ืฉืขื” ื‘ื™ื•ื ื‘ื—ืฆื™ ืฉืขื” ื‘ื™ื•ื ืืคืฉืจ ืœืœืžื•ื“ ืฉืคื” ื—ื“ืฉื” (ืื• ืฉืคืช ืชื›ื ื•ืช ื—ื“ืฉื”). ื‘ื—ืฆื™ ืฉืขื” ื‘ื™ื•ื ืืคืฉืจ ืœื›ืชื•ื‘ ืคืจื•ื™ืงื˜ ืฆื“, ื›ื•ืœืœ ื›ื–ื” ืฉืžื›ื ื™ืก ื›ืกืฃ ืื• ืขื•ืฉื” ืจื•ืฉื ื˜ื•ื‘ ืขืœ ื—ื‘ืจื™ื. ื‘ื—ืฆื™ ืฉืขื” ื‘ื™ื•ื ืืคืฉืจ ืœืœืžื•ื“ ืœืขืฆื‘, ื’ื ืื ื›ืจื’ืข ื–ื” ื ืจืื” ืฉืื™ืŸ ืœืš ื›ื™ืฉืจื•ืŸ. ื‘ื—ืฆื™ ืฉืขื” ื‘ื™ื•ื ืืคืฉืจ ืœื”ื™ื›ื ืก ืœื›ื•ืฉืจ ื•ืœื”ืจื’ื™ืฉ ืžืœืื™ ืื ืจื’ื™ื” ื›ืœ ื”ืฉื‘ื•ืข. ื•ื‘ื˜ื— ืœื›ื ื™ืฉ ืขื•ื“ ืื™ื ืกื•ืฃ ืจืขื™ื•ื ื•ืช ืฉืœ ื“ื‘ืจื™ื ืฉื”ื™ื™ืชื ืจื•ืฆื™ื ืœืขืฉื•ืช. ื”ื‘ืขื™ื” ืขื ื”ื—ืฆื™ ืฉืขื” ื‘ื™ื•ื ื”ื–ืืช ื–ื” ืฉื—ื™ื™ื‘ื™ื ืœื”ืชืžื™ื“. ื–ื” ืœื ืขื•ื–ืจ ืœืขืฉื•ืช ืกืคื•ืจื˜ ืฉื‘ื•ืขื™ื™ื ื•ืื– ืœืขื–ื•ื‘ ืืช ื–ื”, ืื• ืœืœืžื•ื“ ืคื™ื™ืชื•ืŸ ื—ื•ื“ืฉ ื•ืื– ืœื ืœื’ืขืช ื‘ื–ื” ื™ื•ืชืจ. ื”ืขืจืš ืฉืœ "ื—ืฆื™ ืฉืขื” ื‘ื™ื•ื" ืžื’ื™ืข ื‘ื˜ื•ื•ื— ื”ืจื—ื•ืง, ืื—ืจื™ ื—ื•ื“ืฉื™ื ืื• ืฉื ื™ื. ืื‘ืœ ืœื—ืฆื™ ืฉืขื” ื‘ื™ื•ื ืฉืœ ืขื‘ื•ื“ื” ืœื˜ื•ื•ื— ืจื—ื•ืง ื›ืŸ ื™ืฉ ืขืจืš ืžื™ื™ื“ื™ - ื”ื™ื ืžืกืคืงืช ืœื ื• ืชื—ื•ืฉืช ืžืฉืžืขื•ืช, ื’ืื•ื•ื”, ื‘ื™ื˜ื—ื•ืŸ ืขืฆืžื™ ื•ื’ื ืื•ืฉืจ. ื—ืฆื™ ืฉืขื” ื‘ื™ื•ื ืœื˜ื•ื•ื— ื”ืจื—ื•ืง ื–ืืช ื”ื—ืฆื™ ืฉืขื” ืฉื™ืฉ ืœื›ื ื‘ืฉื‘ื™ืœื›ื. ืืœ ืชืžื”ืจื• ืœื•ื•ืชืจ ืขืœื™ื”.

ToCode
1 419
# ืœื”ื‘ื™ืŸ ืฉื™ืฉ ื‘ืขื™ื” ืื—ื“ ื”ื–ื›ืจื•ื ื•ืช ื”ืจืืฉื•ื ื™ื ืฉืœื™ ืžืขื‘ื•ื“ื” ืืžื™ืชื™ืช ื‘ืชื›ื ื•ืช ื”ื•ื ืฉืื—ืจื™ ืฉืกื™ื™ืžืชื™ ืื™ื–ื• ืžืฉื™ืžื” ื”ื™ื™ืชื™ ืฆืจื™ืš ืœืขื“ื›ืŸ ืืช ื”ืื™ื ื“ื ื˜ืฆื™ื” ืฉืœ ื”ืงื•ื“ ืœืžื‘ื ื” ืื—ืจ ืžื–ื” ืฉื”ืขื•ืจืš ืฉืœื™ ื”ื™ื” ืžื›ื•ื•ืŸ ืืœื™ื•. ืฉื™ื ื™ืชื™ ืืช ื”ื’ื“ืจื•ืช ื”ืขื•ืจืš ื•ืขื‘ืจืชื™ ืœืคืชื•ื— ืงื•ื‘ืฅ ืงื•ื‘ืฅ ื•ืœืฉืžื•ืจ ืื•ืชื• ืžื—ื“ืฉ ืขื ื”ืื™ื ื“ื ื˜ืฆื™ื” ื”ื ื›ื•ื ื”. ื—ื‘ืจื” ืฉืจืืชื” ืื•ืชื™ ืžืขื‘ืจ ืœื›ืชืฃ ืขื•ืฉื” ืืช ื”ืขื‘ื•ื“ื” ื”ืกื™ื–ื™ืคื™ืช ื”ื–ื• ื”ืฆื™ืขื” ืฉืื›ืชื•ื‘ ืกืงืจื™ืคื˜ ื‘ืžืงื•ื ื•ื”ืจืืชื” ืœื™ ืื™ืš ืœื”ืฉืชืžืฉ ื‘ perl. ืœืงื— ืœื ื• ืฉืขื•ืช ืœื›ืชื•ื‘ ืืช ื”ืกืงืจื™ืคื˜ ืฉื™ืขื‘ื•ื“ ื›ืžื• ืฉืฆืจื™ืš, ื”ืจื‘ื” ื™ื•ืชืจ ื–ืžืŸ ืžืžื” ืฉื”ื™ื” ืœื•ืงื— ืœื™ ืœืกื™ื™ื ืœืขื‘ื•ืจ ืขืœ ื›ืœ ื”ืงื‘ืฆื™ื ื™ื“ื ื™ืช. ื•ืœืงื— ืœื™ ืฉื‘ื•ืขื•ืช ืœื”ื‘ื™ืŸ ืฉืขืฉื™ื ื• ืืช ื”ื“ื‘ืจ ื”ื ื›ื•ืŸ - ื›ื™ ื‘ืคืขื ื”ื‘ืื” ืฉื”ื™ื” ืฆืจื™ืš ืœืชืงืŸ ืื™ื ื“ื ื˜ืฆื™ื” ื›ื‘ืจ ื”ื™ื• ืœื ื• ืืช ื”ื›ืœื™ื ืœืขื‘ื•ื“ ืžื”ืจ. ื”ืจื‘ื” ืคืขืžื™ื ืœื•ืงื— ื–ืžืŸ ืœื–ื”ื•ืช ืฉื”ื™ืชื” ื‘ืขื™ื” ื‘ืฉื™ื˜ืช ื”ืขื‘ื•ื“ื” ืฉืœื ื• ื•ืฉื™ืฉ ื“ืจืš ื˜ื•ื‘ื” ื™ื•ืชืจ. ืœืื•ืจืš ื–ืžืŸ, ื›ืฉืื ื—ื ื• ื ืฉืืจื™ื ืขื ื”ื›ืœื™ื ื•ืฉื™ื˜ื•ืช ื”ืขื‘ื•ื“ื” ื”ืคื—ื•ืช ื˜ื•ื‘ื™ื, ืจืง ื›ื™ ื–ื” ืžื” ืฉืื ื—ื ื• ืžื›ื™ืจื™ื, ืื ื—ื ื• ืขื•ืฉื™ื ื ื–ืง ืœืขืฆืžื ื• ื•ืœืืจื’ื•ืŸ: 1. ืื ื—ื ื• ื ื›ืชื•ื‘ ื‘ื“ื™ืงื•ืช ื‘ืฆื•ืจื” ืžืกื•ื™ืžืช, ื‘ื˜ื•ื—ื™ื ืฉื–ืืช ื”ื“ืจืš ื”ื™ื—ื™ื“ื” ืื• ื”ื˜ื•ื‘ื” ื‘ื™ื•ืชืจ ืœื›ืชื•ื‘ ื‘ื“ื™ืงื•ืช, ืœืžืจื•ืช ืฉืœื ืžืงื‘ืœื™ื ืžื”ืŸ ืืช ื” ROI ื”ื˜ื•ื‘ ื‘ื™ื•ืชืจ ื”ืืคืฉืจื™. ื›ืฉืžื™ืฉื”ื• ื™ื’ื™ื“ ืžืฉื”ื• ื ืžื”ืจ ืœื”ืกื‘ื™ืจ ืœืžื” ื”ื‘ื“ื™ืงื•ืช ืฉืœื ื• ื”ืŸ ืงืจื™ื˜ื™ื•ืช ืœื”ืฆืœื—ืช ื”ืžืขืจื›ืช. 2. ืื ื—ื ื• ื ืฉืชืžืฉ ื‘ื›ืœื™ื ื‘ืฆื•ืจื” ืžืกื•ื™ืžืช, ื‘ื˜ื•ื—ื™ื ืฉื›ื›ื” ืฆืจื™ืš ืœืขื‘ื•ื“ ืื™ืชื, ืœืžืจื•ืช ืฉืื ืฉื™ื ืื—ืจื™ื ืžืฉืชืžืฉื™ื ื‘ืฆื•ืจื” ื™ื•ืชืจ ื™ืขื™ืœื” ื‘ืื•ืชื ื›ืœื™ื. ื›ืฉื”ื ื™ืจืื• ืœื ื• ืืช ื”ื“ืจืš ืฉืœื”ื ื ืžื”ืจ ืœื”ืกื‘ื™ืจ ืœืžื” ื”ื ื˜ื•ืขื™ื ื•ืœืžื” ื”ืฉื™ื˜ื” ืฉืœื”ื ืœื ืžืชืื™ืžื” ืœื ื•. 3. ืื ื—ื ื• ื ื‘ื—ืจ ื‘ื˜ื›ื ื•ืœื•ื’ื™ื” ืžืกื•ื™ืžืช ื•ื ืขืงื ืื•ืชื” ื›ื“ื™ ืฉืชืชืื™ื ืœืฆืจื›ื™ื ืฉืœื ื•, ืœืžืจื•ืช ืฉื˜ื›ื ื•ืœื•ื’ื™ื” ืื—ืจืช ื”ื™ืชื” ื™ื›ื•ืœื” ืœืขื‘ื•ื“ ื”ืจื‘ื” ื™ื•ืชืจ ื˜ื•ื‘. ืื ืžืฉื”ื• ืœื ืขื•ื‘ื“, ืื ืืชื ืจื•ืื™ื ืฉืืชื ืขื•ื‘ื“ื™ื ืงืฉื” ืžื“ื™ ื‘ืฉื‘ื™ืœ ืœืงื‘ืœ ืชื•ืฆืื” ืฉืื—ืจื™ื ืžืงื‘ืœื™ื ื™ื•ืชืจ ื‘ืงืœื•ืช, ืื ืืชื ื‘ื˜ื•ื—ื™ื ืฉืืฆืœื›ื ื‘ืฆื•ื•ืช ืžืชืžื•ื“ื“ื™ื ืขื ื‘ืขื™ื•ืช ืฉืืฃ ืื—ื“ ืœื ื”ืชืžื•ื“ื“ ืื™ืชืŸ ื‘ืขื‘ืจ - ื™ืฉ ืกื™ื›ื•ื™ ืœื ืจืข ืฉืืชื ืชืงื•ืขื™ื ื‘ื‘ื•ืจ ืฉื—ืคืจืชื ืœืขืฆืžื›ื. ื”ื“ืจืš ืœืฆืืช ืžืžื ื• ื”ื™ื ืงื•ื“ื ื›ืœ ืœืจืื•ืช ืื•ืชื•. ืœื”ื‘ื™ืŸ ืฉื—ืœืง ืžื”ืื™ืœื•ืฆื™ื ืฉืœื›ื ื”ื ืคื™ืงื˜ื™ื‘ื™ื™ื ืื• ืฉืืคืฉืจ ืœืฉื ื•ืช ืื•ืชื, ื•ืฉืฉื•ื•ื” ืœืชืช ื”ื–ื“ืžื ื•ืช ืœื’ื™ืฉื” ืื—ืจืช ื•ืœืชืช ืœื” ืืช ื”ื–ืžืŸ ื›ื“ื™ ืœืจืื•ืช ืชื•ืฆืื•ืช. ืฉื™ืžื•ืฉ ื™ืขื™ืœ ื‘ื›ืœื™ื ืื—ืจื™ื ืœื•ืงื— ื–ืžืŸ, ืื‘ืœ ื–ื” ื›ืžื• ืœืจื›ื‘ ืขืœ ืื•ืคื ื™ื™ื ืขื ื’ืœื’ืœื™ ืขื–ืจ. ื”ื•ืจื“ืช ื’ืœื’ืœื™ ื”ืขื–ืจ, ื’ื ืื ื›ืจื’ืข ื ืจืื™ืช ื”ืจืกื ื™ืช, ืžื”ืจ ืžืื•ื“ ืชืคืชื— ืœื›ื ืืคืฉืจื•ื™ื•ืช ื—ื“ืฉื•ืช ืœื”ืชืงื“ื.

ToCode
1 419
    runner.start(cmd);
    form.current.querySelector('input').value = '';
  }

  return (
    <div className="App">
      <p>{JSON.stringify(runner.lines)}</p>
      <form onSubmit={start} ref={form}>
        <label>
          Command:
          <input type="text" />
        </label>
        <button>Start</button>
      </form>
      <Output />
    </div>
  )
});

export default App
ื•ื›ืžืขื˜ ื‘ืœื™ ืงื•ื“ ื”ืฆืœื—ืชื™ ืœื™ืฆื•ืจ ืงืฉืจ ื“ื• ื›ื™ื•ื•ื ื™ ื‘ื™ืŸ ืงื•ื“ ืฆื“ ืœืงื•ื— ืœืฉืจืช ืคื™ื™ืชื•ืŸ. ืขื ื”ืคื•ืคื•ืœืจื™ื•ืช ืฉืœ ืžืžืฉืงื™ ื•ื•ื‘, ืžื ื’ื ื•ืŸ ื›ื–ื” ื™ื›ื•ืœ ืœืกืคืง ืชื—ืœื™ืฃ ื˜ื•ื‘ ืœื›ืœื™ ืฉื•ืจืช ืคืงื•ื“ื” ืื• ืœื”ืชืžืžืฉืง ืœื›ืœื™ ืฉื•ืจืช ืคืงื•ื“ื” ืงื™ื™ื ืฉืœื›ื. ## ืขื›ืฉื™ื• ืืชื ื”ืงื•ื“ ื›ืจื’ืข ืขื•ื‘ื“ ื•ืžืืคืฉืจ ืœื”ืจื™ืฅ ืคืงื•ื“ื•ืช ืขืœ ื”ืฉืจืช ื•ื’ื ืœืขื‘ื•ื“ ืžื›ืžื” ืœืงื•ื—ื•ืช ื‘ืžืงื‘ื™ืœ. ื”ืงื•ื“ ืœื ืžื˜ืคืœ ื‘ืžืฆื‘ ื‘ื• ืžืฉืชืžืฉ ืžื ืกื” ืœื”ืจื™ืฅ ื›ืžื” ืคืงื•ื“ื•ืช ื‘ืžืงื‘ื™ืœ - ืงื•ื“ ืฆื“ ื”ืœืงื•ื— ื™ืฆื™ื’ ืืช ื”ืคืœื˜ ืฉืœ ืฉืชื™ ื”ืคืงื•ื“ื•ืช ืžืขื•ืจื‘ื‘, ื•ืงื•ื“ ืฆื“ ื”ืฉืจืช ืœื ืžืกืคืง ื›ืจื’ืข ืฉื•ื ื“ืจืš ืœืœืงื•ื— ืœื”ื‘ื“ื™ืœ ืžื” ื”ืคืงื•ื“ื” ืฉื”ื•ื ื”ืจื™ืฅ ืฉื™ืฆืจื” ืืช ื”ืคืœื˜ ืฉื ืฉืœื—. ืชืจื’ื™ืœ ืžืขื ื™ื™ืŸ ืœืžื™ ืฉืจื•ืฆื” ืœืฉื—ืง ืขื ื”ืงื•ื“ ื”ื–ื” ื™ื”ื™ื” ืœื”ื•ืกื™ืฃ ืืช ื”ืชืžื™ื›ื”, ื›ืœื•ืžืจ ืœื”ื•ืกื™ืฃ ืœืžื™ื“ืข ืฉื”ืฉืจืช ืฉื•ืœื— ื’ื ืžื–ื”ื” ืฉืœ ื”ืคืงื•ื“ื” ืฉื”ื•ื ืžืจื™ืฅ, ื•ืœืขื“ื›ืŸ ืืช ืงื•ื“ ืฆื“ ื”ืœืงื•ื— ื›ืš ืฉืืคืฉืจ ื™ื”ื™ื” ืœืจืื•ืช ืฉื•ืจื•ืช ืคืœื˜ ืžื›ืžื” ืคืงื•ื“ื•ืช ื‘ืžืงื‘ื™ืœ, ืื•ืœื™ ื‘ืฆื‘ืขื™ื ืฉื•ื ื™ื ืœืคื™ ื”ืžื–ื”ื” ืฉืœ ื›ืœ ืคืงื•ื“ื”.

ToCode
1 419
# ื‘ื•ืื• ื ื›ืชื•ื‘ ืžืกื•ืฃ ืขื Python, React ื• MobX ื”ืชืžื™ื›ื” ื”ืžืฆื•ื™ื ืช ืฉืœ ืคื™ื™ืชื•ืŸ ื‘ Socket.IO ืžืืคืฉืจืช ืœื ื• ื‘ืžืขื˜ ืžืื•ื“ ืงื•ื“ ืœื›ืชื•ื‘ ืžืžืฉืงื™ื ื’ืจืคื™ื™ื ืœื›ืœื™ ืฉื•ืจืช ืคืงื•ื“ื”. ื‘ื“ื•ื’ืžื” ืฉืœ ื”ื™ื•ื ืื ื™ ืจื•ืฆื” ืœื›ืชื•ื‘ ืžืžืฉืง ื’ืจืคื™ ืœื”ืจืฆื” ืฉืœ ืคืงื•ื“ื•ืช ืขืœ ืžื›ื•ื ื” ืžืจื•ื—ืงืช. ื™ื”ื™ื” ืœื ื• ืฉืจืช ืคื™ื™ืชื•ืŸ ืฉืžืงื‘ืœ ื”ื•ื“ืขื•ืช ื•ืžืจื™ืฅ ืคืงื•ื“ื•ืช, ืืช ื›ืœ ื”ืคืœื˜ ืฉืœ ื”ืคืงื•ื“ื” ื”ื•ื ืฉื•ืœื— ื‘ Web Socket ืœื™ื™ืฉื•ื ืฆื“ ืœืงื•ื— ืœื”ืฆื’ื” ืขืœ ื”ืžืกืš. ## ืงื•ื“ ืฆื“ ืฉืจืช - ืคื™ื™ืชื•ืŸ ื• Socket.IO ื ืชืงื™ืŸ ืืช ื”ืกืคืจื™ื” python-socketio ื•ื’ื ืืช aiohttp, ืฉืชื™ื”ืŸ ืขื pip:
$ pip install aiohttp python-socketio
ื•ืื ื—ื ื• ืžื•ื›ื ื™ื ืœื›ืชื•ื‘ ืงื•ื“ ืฆื“ ืฉืจืช. ื‘ืฉื‘ื™ืœ ืฉืจืช Socket.IO ื‘ืคื™ื™ืชื•ืŸ ืžืกืคื™ืง ืœื›ืชื•ื‘ ืคื•ื ืงืฆื™ื” ืœื›ืœ ื”ื•ื“ืขื” ืฉืื ื—ื ื• ืฆืจื™ื›ื™ื ืœืงื‘ืœ ื•ืœืกืžืŸ ืื•ืชื” ืขื ื” Decorator ื”ืžืชืื™ื. ืื ื™ ืจื•ืฆื” ืœืงื‘ืœ ื”ื•ื“ืขื” ืฉื ืงืจืืช start ื•ืฉื™ื”ื™ื” ืœื” ืคืจืžื˜ืจ ืฉื”ื•ื ื”ื˜ืงืกื˜ ืฉืœ ืฉื•ืจืช ื”ืคืงื•ื“ื” ืœื”ืจืฆื”. ืคื™ื™ืชื•ืŸ ื™ืจื™ืฅ ืืช ื”ืคืงื•ื“ื” ื•ื™ืงืจื ืฉื•ืจื•ืช ืž stdout, ื•ื›ืœ ืฉื•ืจื” ืฉื”ื•ื ืงื•ืจื ื”ื•ื ื™ืฉืœื— ื—ื–ืจื” ืœืฆื“ ืœืงื•ื—. ื‘ืฉื‘ื™ืœ ื–ื” ืžืกืคื™ืง ืœื™ ืงื•ื‘ืฅ ืคื™ื™ืชื•ืŸ ืื—ื“ ืื ื™ ืงื•ืจื ืœื• server.py ืขื ื”ืชื•ื›ืŸ ื”ื‘ื:
from aiohttp import web
import asyncio
import socketio

sio = socketio.AsyncServer(cors_allowed_origins='*', aync_mode='aiohttp')
app = web.Application()

sio.attach(app)

@sio.on('start')
async def start_command(sid, cmd):
    print("Socket ID: " , sid)
    proc = await asyncio.create_subprocess_shell(
        cmd,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE)

    while not proc.stdout.at_eof():
        next_line = await proc.stdout.readline()
        await sio.emit('output', next_line, to=sid)

    await proc.wait()

if __name__ == '__main__':
    web.run_app(app)
ืฉืชื™ ืคื•ื ืงืฆื™ื•ืช ื”ืชืงืฉื•ืจืช ื›ืืŸ ื”ืŸ sio.on ืฉืžื—ื‘ืจืช ืงื•ื“ ื˜ื™ืคื•ืœ ื‘ืื™ืจื•ืข ืœืื™ืจื•ืข ืขื ืฉื ืžืกื•ื™ื (ื‘ื“ื•ื’ืžื” ืฉืœื ื• start) ื• sio.emit ืฉืฉื•ืœื—ืช ืื™ืจื•ืข ืœืœืงื•ื—. ืื ื™ ืžืฉืชืžืฉ ื‘ืคืจืžื˜ืจ to ื›ื“ื™ ืœืฉืœื•ื— ืืช ื”ืคืœื˜ ืจืง ืœืœืงื•ื— ืฉื”ืจื™ืฅ ืืช ื”ืคืงื•ื“ื”. ## ืงื•ื“ ืฆื“ ืœืงื•ื— - ืžื•ื‘ืืงืก ื‘ืฆื“ ื”ืœืงื•ื— ืื ื™ ืจื•ืฆื” ืœื›ืชื•ื‘ ืžื—ืœืงื” ืฉืœ ืœื•ื’ื™ืงื” ืฉื™ื•ื“ืขืช ืœื”ืจื™ืฅ ืคืงื•ื“ื•ืช ื•ืœืฉืžื•ืจ ืืช ื”ืคืœื˜ ืฉืœื”ืŸ. ื™ื”ื™ื” ืœื™ ื ื•ื— ืœื›ืชื•ื‘ ืืช ื”ืœื•ื’ื™ืงื” ื‘ืžื•ื‘ืืงืก ืขื ืžืขืจืš ืฉืฉื•ืžืจ ืืช ื›ืœ ืฉื•ืจื•ืช ื”ืคืœื˜. ื›ืœ ืคืขื ืฉืžื’ื™ืขื” ืฉื•ืจืช ืคืœื˜ ื—ื“ืฉื” ื ื›ืชื•ื‘ ืื•ืชื” ืœืžืขืจืš, ื•ื›ืฉืžืจื™ืฆื™ื ืคืงื•ื“ื” ื—ื“ืฉื” ื ืจื•ืงืŸ ืืช ื”ืžืขืจืš. ืืช ื”ืงื•ื“ ื›ืชื‘ืชื™ ื‘ืงื•ื‘ืฅ ื‘ืฉื runner.js ื‘ืชื•ืš ืชื™ืงื™ื” ื‘ืฉื mobx. ื–ื” ืชื•ื›ืŸ ื”ืงื•ื‘ืฅ:
import { observable, makeObservable, action } from 'mobx';
import { io } from "socket.io-client";

const socket = io("http://localhost:8080");

const enc = new TextDecoder();


class Runner {
  constructor() {
    this.output = [];
    makeObservable(this, {
      clear: action.bound,
      append: action.bound,
      output: observable,
    });
  }

  append(msg) {
    const msgText = enc.decode(msg);
    this.output.push(msgText);
  }

  clear() {
    this.output = [];
  }

  start(cmd) {
    this.clear();
    socket.emit('start', cmd);
  }
}

const runner = new Runner();
socket.on('output', (msg) => {
  runner.append(msg);
});
export default runner;
ื”ืคื•ื ืงืฆื™ื” ื”ื™ื—ื™ื“ื” ืฉืฉื•ื•ื” ืœื”ืชืขื›ื‘ ืขืœื™ื” ื›ืืŸ ื”ื™ื append ื•ืกืคืฆื™ืคื™ืช ืขืœ ืฉื•ืจืช ื”ื”ืžืจื” ื‘ื”:
const enc = new TextDecoder();

// ...
const msgText = enc.decode(msg);
ืื ื—ื ื• ืžืงื‘ืœื™ื ื”ื•ื“ืขื•ืช ืžืคื™ื™ืชื•ืŸ ื‘ืชื•ืจ ืจืฆืคื™ื ืฉืœ ื‘ืชื™ื ื•ืœื ื‘ืชื•ืจ ืžื—ืจื•ื–ื•ืช, ื‘ื’ืœืœ ืฉื›ื›ื” ืขื•ื‘ื“ ื” API ืฉืœ ื”ืจืฆืช ืคืงื•ื“ื•ืช ืžืขืจื›ืช ื‘ืคื™ื™ืชื•ืŸ. ื‘ JavaScript, ืฆืจื™ืš ืœืชืจื’ื ืืช ืื•ืกืฃ ื”ื‘ืชื™ื ื”ื–ื” ืœืžื—ืจื•ื–ืช ื•ื–ื” ื”ืชืคืงื™ื“ ืฉืœ TextDecoder. ืืคืฉืจ ื”ื™ื” ื’ื ืœืขืฉื•ืช ืืช ื”ื”ืžืจื” ื‘ืคื™ื™ืชื•ืŸ ืœืคื ื™ ื”ืฉืœื™ื—ื” ืื ืืชื ืžืจื’ื™ืฉื™ื ื™ื•ืชืจ ื ื•ื— ืฉื. ## ื”ืฆื’ืช ื”ืคืœื˜ ื‘ืžืžืฉืง ืจื™ืืงื˜ ื•ื”ื—ืœืง ื”ืื—ืจื•ืŸ ื”ื•ื ืงื•ื“ ืจื™ืืงื˜ ืฉืžืฆื™ื’ ืชื™ื‘ื” ืœื›ืชื™ื‘ืช ืคืงื•ื“ื” ื•ืงื•ืคืกื” ืฉื‘ื” ืžื•ืฆื’ ื›ืœ ื”ืคืœื˜. ืžืฉืชืžืฉ ื›ื•ืชื‘ ืคืงื•ื“ื” ื‘ืชื™ื‘ื”, ืฉืจืช ืคื™ื™ืชื•ืŸ ืžืจื™ืฅ ืื•ืชื” ื•ืฉื•ืœื— ืืช ื”ืคืœื˜ ื—ื–ืจื” ื•ื”ืฉืชืžืฉ ืžืงื‘ืœ ืืช ื›ืœ ื”ืคืœื˜ ืœืชื™ื‘ืช ื” output. ื–ื” ื”ืงื•ื“ ื‘ืงื•ื‘ืฅ App.jsx:
import { useRef } from 'react'
import { observer } from 'mobx-react-lite';
import runner from './mobx/runner';
import './index.css';

const Output = observer(function Output() {
  return (
    <div className="output">
      <ul>
        {runner.output.map((line, index) => (
          <li key={index}><pre>{line}</pre></li>
        ))}
      </ul>
    </div>
  );
});

const App = observer(function App() {
  const form = useRef(null);
  function start(ev) {
    ev.preventDefault();
    const cmd = form.current.querySelector('input').value;

ToCode
1 419
ื‘ื’ื™ืจืกื 18 ืฉืœ ืจื™ืืงื˜, ืื ืžื•ืกื™ืคื™ื ืงืจื™ืื” ืœ startTransition ื›ืžื• ืฉื”ื•ืกืคืชื™ ื‘ื“ื•ื’ืžื”, ื”ื“ืคื“ืคืŸ ืขื•ืฆืจ ืืช ื”ืจื™ื ื“ื•ืจ ื‘ืืžืฆืข ื›ื“ื™ ืœื˜ืคืœ ื‘ืœื—ื™ืฆื” ืขืœ ื”ื›ืคืชื•ืจ. ื–ื” ื ื•ืชืŸ ืœื“ืคื“ืคืŸ ื”ื–ื“ืžื ื•ืช ืœื˜ืคืœ ื‘ืื™ืจื•ืข mousemove ื‘ืืžืฆืข ื” render ื•ืœืขื“ื›ืŸ ืืช ื”ืžืฉืชื ื” ื”ื’ืœื•ื‘ืืœื™. ื”ืชื•ืฆืื” ื”ื™ื ืฉ-6 ื”ืžื•ืคืขื™ื ืฉืœ MouseTracker ืœื ืžืฆื™ื’ื™ื ืืช ืื•ืชื• ืขืจืš. ืฆืจื™ืš ืœื”ื’ื™ื“ - ื”ื‘ืขื™ื” ื”ื™ื ืœื ืฉ-6 ื”ืงื•ืžืคื•ื ื ื˜ื•ืช ืžืฆื™ื’ื•ืช ื˜ืงืกื˜ ืฉื•ื ื” ื‘ื–ืžื ื™ื ืฉื•ื ื™ื. ืœืคืขืžื™ื ื–ื” ื”ื’ื™ื•ื ื™ ืฉืžืžืฉืง ื™ืชืขื“ื›ืŸ ื‘ื–ืžืŸ ืืžืช ื•ื—ืœืงื™ื ืžืกื•ื™ืžื™ื ื‘ื• ื™ืชืขื“ื›ื ื• ื™ื•ืชืจ ืžื”ืจ ืžืื—ืจื™ื. ื”ื‘ืขื™ื” ืฉืœื ื• ื›ืืŸ ื”ื™ื ืฉืžื‘ื—ื™ื ืช ื”ืžืฉืชืžืฉ ื›ืœ 6 ื”ืžืกืคืจื™ื ืžื•ืฆื’ื™ื ื‘ื“ื™ื•ืง ื‘ืื•ืชื• ื–ืžืŸ, ื›ืœื•ืžืจ ืžืฉืชืžืฉ ืœื•ื—ืฅ ืขืœ ื”ื›ืคืชื•ืจ ืœืฉื™ื ื•ื™ ื”ืขืจืš ืฉืœ count, ืจื™ืืงื˜ ืžืชื—ื™ืœ ืขื‘ื•ื“ื” ื—ื™ืฉื•ื‘ื™ืช ื•ื›ืฉื”ื•ื ืžืกื™ื™ื ืื•ืชื” ื”ื•ื ื›ื•ืชื‘ ืืช ื›ืœ 6 ื”ืžืกืคืจื™ื ืœืžืกืš ื‘ืžื›ื” ืื—ืช. ื‘ืžืฆื‘ ื›ื–ื” ื–ื” ืœื ื”ื’ื™ื•ื ื™ ืœื”ืฆื™ื’ ืขืจืš ืฉื•ื ื” ื‘ื›ืœ ืงื•ืžืคื•ื ื ื˜ื”. ืคื™ืชืจื•ืŸ? ืœื ืœื”ืฉืชืžืฉ ื‘ืžืฉืชื ื™ื ื’ืœื•ื‘ืืœื™ื™ื ืžืชื•ืš ืงื•ืžืคื•ื ื ื˜ื•ืช ืืœื ืœื”ื•ืฆื™ื ืื•ืชื ื”ื—ื•ืฆื” ืœ Store ืžืกื•ื“ืจ, ื•ืœื•ื•ื“ื ืฉื”ืกืคืจื™ื” ืฉืืชื ืžืฉืชืžืฉื™ื ื‘ื” ืœื ื™ื”ื•ืœ ื”ืกื˜ื™ื™ื˜ ื”ื’ืœื•ื‘ืืœื™ ืžืฉืชืžืฉืช ื‘ืคื•ื ืงืฆื™ื” ื—ื“ืฉื” ืฉืœ ืจื™ืืงื˜ 18 ื‘ืฉื useSyncExternalStore. ืคื•ื ืงืฆื™ื” ื–ื• ื‘ืขืฆื ืœื•ืงื—ืช ืžื” Store ื‘ืชื—ื™ืœืช ื” render ืขื•ืชืง ืฉืœ ืื•ืชื• ืžืฉืชื ื” ื’ืœื•ื‘ืืœื™ ื•ื“ื•ืื’ืช ืœื”ืขื‘ื™ืจ ืื•ืชื• ื‘ render ืœื›ืœ ื”ืงื•ืžืคื•ื ื ื˜ื•ืช ืฉืžืกืชืžื›ื•ืช ืขืœื™ื•. ืื ืืชื ืกืงืจื ื™ื ืื™ืš ื–ื” ืขื•ื‘ื“ ืžืื—ื•ืจื™ ื”ืงืœืขื™ื ืฉื•ื•ื” ืœืฆืคื•ืช ื‘ื”ืจืฆืื” ืฉืœ ื“ืื™ืฉื™.

ToCode
1 419
# ืžื” ื–ื” Tearing ื‘ React ื•ืœืžื” ืฉื™ื”ื™ื” ืœื›ื ืื›ืคืช ื’ื™ืจืกื” 18 ืฉืœ ืจื™ืืงื˜ ื”ื›ื ื™ืกื” ืœืฉื™ืžื•ืฉ ืžื ื’ื ื•ืŸ ื—ื“ืฉ ืฉื ืงืจื Concurrent Mode. ืื ืืชื ื‘ื•ื ื™ื ืืคืœื™ืงืฆื™ื™ืช ืจื™ืืงื˜ ื—ื“ืฉื” ื‘ Vite ืื• create-react-app, ื”ืžื ื’ื ื•ืŸ ืžื•ืคืขืœ ื›ื‘ืจื™ืจืช ืžื—ื“ืœ. ืื ืืชื ืžืฉื“ืจื’ื™ื ืืคืœื™ืงืฆื™ื” ื™ืฉื ื” ืœืจื™ืืงื˜ 18 ืืชื ืชืงื‘ืœื• ื”ื•ื“ืขื” ืฉืžื‘ืงืฉืช ืžื›ื ืœื”ื—ืœื™ืฃ ืืช ืคืงื•ื“ืช ื” ReactDOM.render ื‘ืคืงื•ื“ื” ื‘ืฉื ReactDOM.createRoot ื›ื“ื™ ืœื”ืคืขื™ืœ ืืช ื”ืžื ื’ื ื•ืŸ. ืžื ื’ื ื•ืŸ ื” Concurrent Mode ืืžื•ืจ ืœืขื–ื•ืจ ืœืคืชื•ืจ ื‘ืขื™ื•ืช ื‘ื™ืฆื•ืขื™ื ืฉื ื•ื‘ืขื•ืช ืž render-ื™ื ืืจื•ื›ื™ื ืžื“ื™. ืžื ื’ื ื•ืŸ Concurrent Mode ืžื•ืกื™ืฃ ืคื•ื ืงืฆื™ื” ื‘ืฉื startTransition ืฉืžืืคืฉืจืช ืœื ื• ืœืกืžืŸ ืฉืขื“ื›ื•ืŸ ืžืกื•ื™ื ื”ื•ื ื—ืฉื•ื‘ ื•ืฆืจื™ืš ืœื”ืคืกื™ืง render-ื™ื ืคื—ื•ืช ื—ืฉื•ื‘ื™ื ื•ืžื”ืจ ืžื”ืจ ืœืขืฉื•ืช render ื—ื“ืฉ ืจืง ื‘ืฉื‘ื™ืœ ื”ืฉื™ื ื•ื™ ื”ื–ื”. ืœื›ืื•ืจื” ืคื™ืฆ'ืจ ื ื—ืžื“ ื•ืœื ืžื–ื™ืง ืฉืืคื™ืœื• ื™ื›ื•ืœ ืœืขื–ื•ืจ ืœื‘ื™ืฆื•ืขื™ื, ืื‘ืœ ื”ืืžืช ืงืฆืช ื™ื•ืชืจ ืžื•ืจื›ื‘ืช ื•ื”ื™ื ืขืœื•ืœื” ืœืงืคื•ืฅ ืขืœื™ื›ื ื‘ื”ืคืชืขื”. ืืช ื”ืžื•ืฉื’ tearing ื‘ื”ืงืฉืจ ืฉืœ ื‘ืขื™ื™ืช UI ืœื ืžืฆืืชื™ ื‘ืชื™ืขื•ื“ ืฉืœ ืจื™ืืงื˜ ืื• ื‘ื”ื›ืจื–ื” ืขืœ ืจื™ืืงื˜ 18, ืืœื ืจืง ืžืคื•ืกื˜ื™ื ืื—ืจื™ื ืฉื“ื™ื‘ืจื• ืขืœ ื”ื‘ืขื™ื” ื•ื”ืจืฆืื” ืžืฆื•ื™ื ืช ื‘ื™ื•ื˜ื™ื•ื‘ ืฉืœ Daishi Kato. ืื ื™ืฉ ืœื›ื 20 ื“ืงื•ืช ืคื ื•ื™ื•ืช ืฉื•ื•ื” ืœื”ืงืฉื™ื‘ ืœื•: https://www.youtube.com/watch?v=oPfSC5bQPR8. ื‘ื—ื–ืจื” ืœ Tearing - ื‘ื”ืงืฉืจ ืฉืœ ืจื™ืืงื˜ ื”ืžื•ืฉื’ ืžืชืืจ ืžืฆื‘ ื‘ื• Concurrent Mode ื’ื•ืจื ืœ UI ืœื”ื™ื•ืช ืœื ืงื•ื ืกื™ืกื˜ื ื˜ื™ ื‘ื’ืœืœ ืฉื™ื ื•ื™ ืžืฉืชื ื™ื ื’ืœื•ื‘ืืœื™ื™ื. ื”ื‘ืขื™ื” ื”ื™ื ื›ื–ืืช: 1. ื™ืฉ ืœื ื• ื›ืžื” ืงื•ืžืคื•ื ื ื˜ื•ืช ืฉืžื•ืฉืคืขื•ืช ืžืžืฉืชื ื” ื’ืœื•ื‘ืืœื™ - ื–ื” ื™ื›ื•ืœ ืœื”ื™ื•ืช ref, ืžืฉืชื ื” ืฉืฉืžื•ืจ ื‘ Store ื—ื™ืฆื•ื ื™, ืื• ืืคื™ืœื• ื”ืชืืจื™ืš ืื• ื”ืฉืขื” ื”ื ื•ื›ื—ื™ื™ื ืฉื ืœืงื—ื™ื ืžื”ื“ืคื“ืคืŸ. 2. ื‘ืืžืฆืข ืฉืจื™ืืงื˜ ืขื•ืฉื” render ืœืงื•ืžืคื•ื ื ื˜ื•ืช ื”ืืœื”, ืคืชืื•ื ื”ื•ื ืžื’ืœื” ืฉื™ืฉ ืฉื™ื ื•ื™ ื™ื•ืชืจ ื“ื—ื•ืฃ ื›ื™ ืžื™ืฉื”ื• ืงืจื ืœ startTransition. ืื– ืจื™ืืงื˜ ืขื•ืฆืจ ื”ื›ืœ ื•ื”ื•ืœืš ืœืขืฉื•ืช ืืช ื” render ื”ื™ื•ืชืจ ื“ื—ื•ืฃ ืฉืœื•. ื‘ื•ืื• ื ื’ื™ื“ ืฉื”ื™ื• ืœื™ 6 ืงื•ืžืคื•ื ื ื˜ื•ืช ืฉืžื•ืฉืคืขื•ืช ืžืžืฉืชื ื” ื’ืœื•ื‘ืืœื™, ื•ืจื™ืืงื˜ ืจื™ื ื“ืจ 3 ืžื”ืŸ ืœืคื ื™ ืฉื”ื™ื” ืฆืจื™ืš ืœืขืฆื•ืจ. 3. ืชื•ืš ื›ื“ื™ ื” render ื”ื™ื•ืชืจ ื“ื—ื•ืฃ, ื”ืขืจืš ืฉืœ ื”ืžืฉืชื ื” ื”ื’ืœื•ื‘ืืœื™ ืžืฉืชื ื”. 4. ื›ืฉืจื™ืืงื˜ ื—ื•ื–ืจ ืœืจื ื“ืจ ืืช 3 ื”ืงื•ืžืคื•ื ื ื˜ื•ืช ืฉื ืฉืืจื•, ื”ื•ื ืžืจื ื“ืจ ืื•ืชืŸ ืœืคื™ ื”ืขืจืš ื”ื—ื“ืฉ ืฉืœ ืื•ืชื• ืžืฉืชื ื” ื’ืœื•ื‘ืืœื™. 5. ืจื™ืืงื˜ ืžืฆื™ื’ ืขืœ ื”ืžืกืš ืืช ื›ืœ 6 ื”ืงื•ืžืคื•ื ื ื˜ื•ืช ื‘ืžื›ื” ืื—ืช, ืœืžืจื•ืช ืฉื”ืŸ ืจื•ื ื“ืจื• ื‘ื–ืžื ื™ื ืฉื•ื ื™ื ื•ืขื ืขืจื›ื™ื ืฉื•ื ื™ื ืฉืœ ื”ืžืฉืชื ื” ื”ื’ืœื•ื‘ืืœื™. ืขืœ ื”ืžืกืš ืื ื—ื ื• ืจื•ืื™ื ืžืžืฉืง ืœื ืงื•ื ืกื™ืกื˜ื ื˜ื™. ื—ืฆื™ ืžื”ืžืžืฉืง ืžืชื‘ืกืก ืขืœ ืขืจืš ื™ืฉืŸ ืฉืœ ื”ืžืฉืชื ื” ื”ื’ืœื•ื‘ืืœื™, ื•ื”ื—ืฆื™ ื”ืฉื ื™ ืขืœ ื”ืขืจืš ื”ื—ื“ืฉ. ื“ืื™ืฉื™ ื”ืจืื” ื‘ื”ืจืฆืื” ื“ื•ื’ืžื” ืžืขื ื™ื™ื ืช, ืื—ืจื™ ืฉืฆืžืฆืžืชื™ ืื•ืชื” ืงืฆืช ื”ื’ืขืชื™ ืœืงื•ื“ ื”ื–ื” ืฉืžืžื—ื™ืฉ ื‘ื“ื™ื•ืง ืืช ื”ื‘ืขื™ื”:
import { useState, useTransition } from 'react'

let lastMouseX = 0;

window.addEventListener('mousemove', (e) => {
  lastMouseX = e.offsetX;
});

function MouseTracker() {
  const start = performance.now();
  while (performance.now() - start < 20);
  
  return (
    <p>{lastMouseX}</p>
  );
}

function App() {
  const [count, setCount] = useState(0)
  const [isPending, startTransition] = useTransition();

  return (
    <div className="App">
      <p>isPending = {JSON.stringify(isPending)}</p>
      <button onClick={() => {
        startTransition(() => {
          setCount(c => c + 1)
        });
      }}>{count}</button>
      <MouseTracker />
      <MouseTracker />
      <MouseTracker />
      <MouseTracker />
      <MouseTracker />
      <MouseTracker />
    </div>
  )
}

export default App
ื™ืฉ ืœื ื• ืžืฉืชื ื” ื’ืœื•ื‘ืืœื™ ื‘ืฉื lastMouseX ืฉื”ืขืจืš ืฉืœื• ืžืฉืชื ื” ื›ืœ ืคืขื ืฉืžื–ื™ื–ื™ื ืืช ื”ืขื›ื‘ืจ. ื™ืฉ ืœื ื• ื’ื 6 ืงื•ืžืคื•ื ื ื˜ื•ืช ืžืกื•ื’ MouseTracker ืฉืคืฉื•ื˜ ืžืฆื™ื’ื•ืช ืืช ื”ืขืจืš. ื‘ืฉื‘ื™ืœ ืฉื” render ืฉืœื”ืŸ ื™ื™ืงื— ื–ืžืŸ ื•ืœืจื™ืืงื˜ ืชื”ื™ื” ื”ื–ื“ืžื ื•ืช ืœืขืฉื•ืช ื›ืžื” ื“ื‘ืจื™ื ื‘ืžืงื‘ื™ืœ ื”ื•ืกืคืชื™ ืงื•ื“ ืฉืœ ื”ืžืชื ื” ื‘ืชื•ืš ืงื•ื“ ื”ืงื•ืžืคื•ื ื ื˜ื”. ื‘ืขื•ืœื ื”ืืžื™ืชื™ ื–ื” ื™ื›ื•ืœ ืœื”ื™ื•ืช ื—ื™ืฉื•ื‘ ืืจื•ืš ืื• ืžืกื•ื‘ืš. ื‘ื’ื™ืจืกืื•ืช ื™ืฉื ื•ืช ืฉืœ ืจื™ืืงื˜ ืœื ืžืฉื ื” ืžื” ื”ื™ื™ื ื• ืขื•ืฉื™ื ืชืžื™ื“ ื”ื™ื™ื ื• ืžืงื‘ืœื™ื ืืช ืื•ืชื• ืขืจืš ืฉืœ lastMouseX ืžื•ืคื™ืข 6 ืคืขืžื™ื. ื‘ื–ืžืŸ ืฉืจื™ืืงื˜ ืขืกื•ืง ื‘ render, ื”ื“ืคื“ืคืŸ ืœื ืžืคืขื™ืœ ืืช ื” callback ืฉืžื˜ืคืœ ื‘ื˜ื™ืคื•ืœ ื‘ืื™ืจื•ืข. ืจืง ืื—ืจื™ ืฉื” render ืžืกืชื™ื™ื ืœื“ืคื“ืคืŸ ื™ืฉ ื”ื–ื“ืžื ื•ืช ืœืขื“ื›ืŸ ืืช ื”ืžืฉืชื ื” ื”ื’ืœื•ื‘ืืœื™ ื•ืื ื—ื ื• ื ืงื‘ืœ ืืช ื”ืขืจืš ื”ื—ื“ืฉ ื‘ืคืขื ื”ื‘ืื” ืฉื ืœื—ืฅ ืขืœ ื”ื›ืคืชื•ืจ ืฉืžืจื ื“ืจ ืžื—ื“ืฉ ืืช ื”ืงื•ืžืคื•ื ื ื˜ื”. ื‘ื’ื™ืจืกื 18 ืฉืœ ืจื™ืืงื˜ ืœืคื ื™ Concurrent Mode, ืื• ืื ืœื ืงื•ืจืื™ื ืœ startTransition, ืจื™ืืงื˜ ืžื‘ืฆืข ืืช ื” render "ื‘ืžื›ื” ืื—ืช" ื›ืžื• ื‘ื’ื™ืจืกืื•ืช ื”ื™ืฉื ื•ืช, ื•ืฉื•ื‘ ืœื“ืคื“ืคืŸ ืื™ืŸ ื”ื–ื“ืžื ื•ืช ืœืฉื ื•ืช ืืช ื”ืขืจืš ืฉืœ ื”ืžืฉืชื ื” ื”ื’ืœื•ื‘ืืœื™ ื‘ื™ืŸ ืจื™ื ื“ื•ืจ ืฉืœ ืงื•ืžืคื•ื ื ื˜ื•ืช.

ToCode
1 419
# ืงื•ื“ ืฉืื ื™ ืœื ืจื•ืฆื” ืœื›ืชื•ื‘ ื›ืชื‘ืชื™ ื”ืฉื‘ื•ืข ืงื•ื“ ืชืงืฉื•ืจืช ืฆื“ ืœืงื•ื— ืžืืคืก, ื›ืœื•ืžืจ ื‘ืœื™ ืกืคืจื™ื” ื›ืžื• react-query ืื• swr. ื”ืงื•ื“ ืžืฉืš ืžื™ื“ืข ืžื”ืฉืจืช ื•ื’ื ืฉืžืจ ืื•ืชื• ื‘ cache ืžืงื•ืžื™, ื”ื’ื‘ื™ืœ ืืช ืžืกืคืจ ื”ืชืฉื•ื‘ื•ืช ืฉืฉืžื•ืจื•ืช ื‘ cache ื•ืืช ื”ื–ืžืŸ ื‘ื• ืฉื•ืžืจื™ื ืื•ืชืŸ ื•ื˜ื™ืคืœ ื‘ื›ืœ ืžื™ื ื™ ืžืงืจื™ ืงืฆื”. ื›ื›ืœ ืฉื”ืชืงื“ืžืชื™ ืฉื•ืจื” ื•ืขื•ื“ ืฉื•ืจื” ื—ืฉื‘ืชื™ - ืดืœืžื” ืื ื™ ืฆืจื™ืš ืœื›ืชื•ื‘ ืืช ื–ื”? ื‘ื˜ื— ืžื™ืฉื”ื• ื›ื‘ืจ ื›ืชื‘ ืืช ื–ื” ืงื•ื“ืืด ืดื—ื™ื™ื‘ืช ืœื”ื™ื•ืช ืกืคืจื™ื” ืฉืขื•ืฉื” ืืช ื–ื”... ืื ื™ ืœื ืžืืžื™ืŸ ืฉืื ื™ ืžื‘ื–ื‘ื– ื›ื›ื” ืืช ื”ื–ืžืŸืด ืดื™ื• ืื ื™ ื‘ื˜ื— ืžืคืกืคืก ืคื” ืžืœื ืžืงืจื™ ืงืฆื”, ื‘ื—ื™ื™ื ืœื ืืฆืœื™ื— ืœืชืคื•ืก ื•ืœืชืงืŸ ืืช ื›ื•ืœืืด ืดืื™ืŸ ืžืฆื‘ ืฉื–ื” ื™ืขื‘ื•ื“ ื›ืžื• ืฉืฆืจื™ืš ืขืœ ื›ืœ ื”ื“ืคื“ืคื ื™ื ื•ืื™ืŸ ืกื™ื›ื•ื™ ืฉืื ื™ ืžื•ืฆื ื–ืžืŸ ืœื‘ื“ื•ืง ืืช ื–ื” ืขืœ ื›ืœ ืžื›ืฉื™ืจืด ืดืขื•ื“ ืคืขื if ??? ื–ื” ื›ื‘ืจ ื”ื—ืžื™ืฉื™ ืฉืœื™ ื‘ืคื•ื ืงืฆื™ื”. ืœืžื” ื›ืœ ื›ืš ื”ืจื‘ื” ื“ื‘ืจื™ื ื™ื›ื•ืœื™ื ืœื”ืฉืชื‘ืฉ!?ืด ื•ื›ื›ืœ ืฉืื ื™ ื—ื•ืคืจ ื‘ืžื—ืฉื‘ื•ืช ื”ืืœื” ื‘ืžืงื•ื ืœื›ืชื•ื‘ ืงื•ื“ ื”ืœื›ืชื™ ืœื”ืกืชื›ืœ ื‘ืงื•ื“ ืฉืœ ืกืคืจื™ื•ืช ืฉืขื•ืฉื•ืช ื“ื‘ืจื™ื ื“ื•ืžื™ื (ื›ื™ ื ื•, ืื™ืŸ ื“ื‘ืจ ืฉืžืขื•ื“ื“ ื‘ื–ื‘ื•ื– ื–ืžืŸ ื™ื•ืชืจ ืžืืฉืจ ืงื•ื“ ืฉืืชื” ืœื ืจื•ืฆื” ืœื›ืชื•ื‘). ื™ื›ื•ืœื™ื ืœื ื—ืฉ ืžื” ืžืฆืืชื™ ืฉื? ื ื›ื•ืŸ, ื‘ื“ื™ื•ืง ืืช ืื•ืชื• ืงื•ื“ ืฉืื ื™ ืœื ืจืฆื™ืชื™ ืœื›ืชื•ื‘. ืืช ื”ื˜ื™ืคื•ืœ ื‘ืื•ืชื ืžืงืจื™ ืงืฆื”, ืืช ื”ื‘ื“ื™ืงื•ืช ื•ืืช ื” if-ื™ื. ื”ืจืฆื•ืŸ ืœื›ืชื•ื‘ ืจืง ืงื•ื“ "ื ืงื™" ื•"ื™ืคื”" ื”ื•ื ื ื—ืžื“, ืื‘ืœ ื”ื—ื™ื™ื ื”ื ืœื ืกืคืจ ืœื™ืžื•ื“. ื”ืจื‘ื” ืžืงื˜ืขื™ ื”ืงื•ื“ ืฉืžืคืขื™ืœื™ื ืืช ื”ื—ื™ื™ื ืฉืœื ื• ืžืœืื™ื ื‘ื˜ื™ืคื•ืœ ื‘ืื™ื ืกื•ืฃ ืžืงืจื™ ืงืฆื”, ื‘ืื™ื ืกื•ืฃ "ืคืœืกื˜ืจื™ื" ืฉืžืชื›ื ืชื™ื ื”ื“ื‘ื™ืงื• ื›ืœ ืคืขื ืฉื ืชืงืœื• ื‘ื‘ืขื™ื” ื—ื“ืฉื” ืื• ืชื™ืงื ื• ื‘ืื’ ื—ื“ืฉ. ื•ื•ื™ืชื•ืจ ืขืœ ื›ืชื™ื‘ืช ืงื•ื“ ื›ื–ื”, ืจืง ื›ื™ "ื—ื™ื™ื‘ืช ืœื”ื™ื•ืช ื“ืจืš ื˜ื•ื‘ื” ื™ื•ืชืจ", ื•ืฉื™ืœื•ื‘ ืกืคืจื™ื” ื—ื™ืฆื•ื ื™ืช ื‘ืžืงื•ื ืœื ื”ื•ืคืš ืืช ื”ืžืขืจื›ืช ืœื ืงื™ื” ื™ื•ืชืจ - ื”ื•ื ืคืฉื•ื˜ ืžืขื‘ื™ืจ ืืช ื”ืœื›ืœื•ืš ืœืžืงื•ื ืฉืงืฉื” ืœืจืื•ืช ืื•ืชื•. ืœืคืขืžื™ื, ื›ืฉื™ืฉ ืกืคืจื™ื” ื—ื™ืฆื•ื ื™ืช ื˜ื•ื‘ื” ื•ืžืชื•ื—ื–ืงืช ื–ื” ื›ื“ืื™. ื›ืฉืื™ืŸ ืื—ืช ื›ื–ืืช ืฆืจื™ืš ื’ื ืงืฆืช ืœื”ืชืœื›ืœืš ืœืคืขืžื™ื. (ื .ื‘. ื”ื“ืจืš ื”ื™ื—ื™ื“ื” ืœื›ืชื•ื‘ ืงื•ื“ ืฉืžื˜ืคืœ ื‘ื”ืžื•ืŸ ืžืงืจื™ ืงืฆื” ื‘ืœื™ ืœื”ืฉืชื’ืข ื ืงืจืืช ื‘ื“ื™ืงื•ืช. ื‘ืœืขื“ื™ื”ืŸ, ืกื’ื™ืจื” ืฉืœ ื›ืœ ื—ื•ืจ ื—ื“ืฉ ืคื•ืชื—ืช 3 ื—ื•ืจื™ื ืงื•ื“ืžื™ื ืฉื—ืฉื‘ืชื ืฉืกื’ืจืชื).

ToCode
1 419
              Object.values(this.items),
              (i) => i.index
            );
            delete this.items[oldestItem.id];
          }
        });
      });
  }
ื•ืขื›ืฉื™ื• ื’ื ื”ื”ื›ื ืกื” ื•ื’ื ื”ืžื—ื™ืงื” ืžืชื‘ืฆืขื•ืช ื‘ื˜ืจื ื–ืืงืฆื™ื” ืื—ืช ื•ื™ื•ื‘ื™ืœื• ืœ render ื™ื—ื™ื“. ืžื•ื–ืžื ื™ื ืœืจืื•ืช ืืช ื”ืงื•ื“ ื•ืœืฉื—ืง ืื™ืชื• ื‘ืงื•ื“ืกื ื“ื‘ื•ืงืก ื‘ืงื™ืฉื•ืจ: https://codesandbox.io/s/distracted-gagarin-qve7lc?file=/src/mobx/swapi.js ืื• ื‘ื”ื˜ืžืขื” ื›ืืŸ: <iframe src="https://codesandbox.io/embed/distracted-gagarin-qve7lc?fontsize=14&hidenavigation=1&theme=dark" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" title="distracted-gagarin-qve7lc" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" ></iframe> ## ืกื™ื›ื•ื - ื˜ื™ืคื™ื ืœืฉื™ืžื•ืฉ ื‘ MobX ืžื•ื‘ืืงืก ื”ื•ื ืกืคืจื™ื” ืจื™ืืงื˜ื™ื‘ื™ืช ืœื ื™ื”ื•ืœ ืกื˜ื™ื™ื˜ ื’ืœื•ื‘ืืœื™. ื›ืฉืžืฉืชืžืฉื™ื ื‘ื• ื ื›ื•ืŸ ื”ื•ื ื™ื›ื•ืœ ืœืขื–ื•ืจ ืœื ื• ืœื›ืชื•ื‘ ื™ื™ืฉื•ืžื™ ืฆื“-ืœืงื•ื— ื ืงื™ื™ื ื•ืงืœื™ื ืœืชื—ื–ื•ืงื”. ืœืกื™ื›ื•ื ื”ืคื•ืกื˜ ืืœื” ื”ื ืงื•ื“ื•ืช ื”ืžืจื›ื–ื™ื•ืช ืฉืฆืจื™ืš ืœืฉื™ื ืœื‘ ืืœื™ื”ืŸ ื‘ืขื‘ื•ื“ื” ืขื ืžื•ื‘ืืงืก: 1. ืฉื™ืžื• ืœื‘ ืœืจื™ืืงื˜ื™ื‘ื™ื•ืช. ืžื”ื• ืžืฉืชื ื” ืจื™ืืงื˜ื™ื‘ื™, ืžืชื™ ื”ื•ื ืžืชืขื“ื›ืŸ ื•ืžื™ ืขื•ืงื‘ ืื—ืจื™ื•. ืžืฉืชื ื™ื ืจื™ืืงื˜ื™ื‘ื™ื™ื ื“ื•ืจืฉื™ื ืžืขืงื‘ ืฆืžื•ื“ ื‘ื”ืจื‘ื” ืžืžืฉืชื ื™ื ืจื’ื™ืœื™ื ื›ื™ ื”ื ื›ืžื• ืžื ื’ื ื•ืŸ ืื™ืจื•ืขื™ื ืžื•ื‘ื ื” ื‘ืชื•ืš ื”ืžื—ืœืงื”. 2. ืฉื™ืžื• ืœื‘ ืžืชื™ ื ื™ื’ืฉื™ื ืœืžืฉืชื ื™ื ืจื™ืืงื˜ื™ื‘ื™ื™ื. ื›ืœ ื’ื™ืฉื” ืœืžืฉืชื ื” ืจื™ืืงื˜ื™ื‘ื™ ื™ื•ืฆืจืช ื™ื—ืก ืฉืœ ื”ืื–ื ื” ืœืฉื™ื ื•ื™ื™ื ื‘ืžืฉืชื ื” ื–ื”. 3. ื”ืชื—ื™ืœื• ืขื ืžื•ื‘ืืงืก ื•ื‘ื ื™ื™ืช ื›ืœ ื”ืœื•ื’ื™ืงื” ื•ื”ืคืขื•ืœื•ืช ื‘ืžื ื•ืชืง ืžื” UI, ื•ืจืง ืื—ืจ ื›ืš ืžืžืฉื• ืืช ื” UI ื‘ืชื•ืจ ืฉื›ื‘ื” ื“ืงื” ืฉืœ ื’ื™ืฉื” ืœืžื™ื“ืข. ื‘ื”ืฉื•ื•ืื” ื”ืงืœืืกื™ืช ื‘ื™ืŸ ืจื™ื“ืืงืก ืœืžื•ื‘ืืงืก ืื ื™ ืœื ื—ื•ืฉื‘ ืฉืžื•ื‘ืืงืก ื™ื•ืชืจ ืคืฉื•ื˜ ืžืจื™ื“ืืงืก ืื• ืœื”ื™ืคืš. ื”ื ืคืฉื•ื˜ ืฉื•ื ื™ื. ืœื ืžืฉื ื” ืื™ื–ื” ืžื”ืฉื ื™ื™ื ืชื‘ื—ืจื•, ื”ื™ื›ืจื•ืช ื˜ื•ื‘ื” ืขื ืฉื™ื˜ืช ื”ืขื‘ื•ื“ื” ืขื•ื–ืจืช ืœื›ืชื•ื‘ ืงื•ื“ ื ืงื™ ื•ืžื“ื•ื™ืง ื™ื•ืชืจ.

ToCode
1 419
          delete this.items[oldestItem.id];
        }
      });
  }
}

export const charactersRepo = new Repo("https://swapi.dev/api/people");
ื”ืงื•ื‘ืฅ ืžื™ื™ืฆื ืื•ื‘ื™ืงื˜ Repo ืฉืžื—ื•ื‘ืจ ืœ REST Endpoint ืขื‘ื•ืจ ื“ืžื•ื™ื•ืช ืžืžืœื—ืžืช ื”ื›ื•ื›ื‘ื™ื. ื‘ืฆื“ ืฉืœ ืจื™ืืงื˜ ืื ื™ ืจื•ืฆื” ืœื‘ื ื•ืช ืงื•ืžืคื•ื ื ื˜ื” ืฉืžืฉืชืžืฉืช ื‘ืจื™ืคื• ืฉื™ืฆืจืชื™ ื›ื“ื™ ืœื”ืฆื™ื’ ืžื™ื“ืข ืขืœ ื“ืžื•ื™ื•ืช ืžืžืœื—ืžืช ื”ื›ื•ื›ื‘ื™ื. ื”ืงื•ืžืคื•ื ื ื˜ื” ืชื—ื–ื™ืง ืžืฉืชื ื” ืกื˜ื™ื™ื˜ ืฉืžื™ื™ืฆื’ ืืช ื”ื“ืžื•ืช ืฉืขื›ืฉื™ื• ืžื•ืฆื’ืช, ื›ืœ ืคืขื ืฉื”ื•ื ื™ืชืขื“ื›ืŸ ื”ื™ื ืชื‘ืงืฉ ืžืจื™ืคื• ืœื‘ืฆืข fetch ืœืžื™ื“ืข ืฉืœ ืื•ืชื” ื“ืžื•ืช, ื•ื›ืฉื”ืžื™ื“ืข ื™ื”ื™ื” ืžื•ื›ืŸ ื”ืงื•ืžืคื•ื ื ื˜ื” ืชืฆื™ื’ ืื•ืชื•. ื›ืš ื ืจืื” ื”ืงื•ื“:
const SWCharacter = observer(function SWCharacter() {
  const [id, setId] = useState("");
  const data = charactersRepo.items[id]?.data;

  useEffect(() => {
    if (id !== "") {
      charactersRepo.fetch(id);
    }
  }, [id]);

  console.log(`render items id = ${id}`);

  return (
    <div>
      <input type="number" value={id} onChange={(e) => setId(e.target.value)} />
      {data && (
        <div>
          <p>Name: {data.name}</p>
          <p>Birth Year: {data.birth_year}</p>
        </div>
      )}
    </div>
  );
});
ื”ื—ืœืง ื”ืจืืฉื•ืŸ ื‘ืงื•ื“ ื”ืงื•ืžืคื•ื ื ื˜ื” ืฉืงืฉื•ืจ ืœืจื™ืืงื˜ื™ื‘ื™ื•ืช ื”ื•ื ื”ืฉื•ืจื”:
const data = charactersRepo.items[id]?.data;
ืฉื•ืจื” ื–ื• ื ื™ื’ืฉืช ืœืื•ื‘ื™ืงื˜ items ืฉืœ ื”ืจื™ืคื• ื‘ืžืคืชื— id ืฉืœื•. ืื ื™ืฉ ืฉื ืžืฉื”ื• ื”ื™ื ืชื™ืงื— ืืช ืฉื“ื” data ืฉืœื•, ืฉื–ื” ื”ืžื™ื“ืข ืฉืœืงื—ื ื• ื›ื‘ืจ ืžื”ืฉืจืช (ืื•ืœื™ ื‘ืชื’ื•ื‘ื” ืœื‘ืงืฉื” ืื—ืจืช). ื™ื•ืชืจ ืžืขื ื™ื™ืŸ ืžื” ืงื•ืจื” ืื ื–ื” ืœื ืงื™ื™ื. ื‘ืžืฆื‘ ื›ื–ื” ืื ื—ื ื• ื ืงื‘ืœ undefined, ืื‘ืœ ืžื•ื‘ืืงืก ื’ื ืžืกืžืŸ ืฉื ื™ืกื™ื ื• ืœื’ืฉืช ืœืื•ื‘ื™ืงื˜ ื‘ืžื–ื”ื” id. ืื ื‘ืขืชื™ื“ ื”ืขืจืš ื‘ืžื–ื”ื” ื”ื–ื” ื™ืฉืชื ื”, ื‘ืื•ืคืŸ ืื•ื˜ื•ืžื˜ื™ ื”ืงื•ืžืคื•ื ื ื˜ื” ืชืจื•ื ื“ืจ ืžื—ื“ืฉ ื•ืชืงื‘ืœ ื”ื–ื“ืžื ื•ืช ื ื•ืกืคืช ืœืงื—ืช ืืช ื”ืขืจืš ื”ื—ื“ืฉ ืžืฉื. ื”ื—ืœืง ื”ืฉื ื™ ื”ื•ื ื”ืืคืงื˜:
useEffect(() => {
  if (id !== "") {
    charactersRepo.fetch(id);
  }
}, [id]);
ื›ืœ ืคืขื ืฉ id ืžืฉืชื ื” ื•ื”ืขืจืš ื”ื—ื“ืฉ ืื™ื ื• ืžื—ืจื•ื–ืช ืจื™ืงื”, ืชื•ืคืขืœ ื”ืคื•ื ืงืฆื™ื” fetch ืขื ื” id ื”ื—ื“ืฉ. ื‘ืจื’ืข ืฉ fetch ืžืกื™ื™ืžืช ื•ืžืขื“ื›ื ืช ืืช items ื‘ืžืคืชื— id, ื‘ืฆื•ืจื” ืื•ื˜ื•ืžื˜ื™ืช ื”ืงื•ืžืคื•ื ื ื˜ื” ืชืชืขื“ื›ืŸ ืžื—ื“ืฉ ืขื ื”ืขืจืš ืฉื ืฉืžืจ ื•ื”ื›ืœ ืคืฉื•ื˜ ื™ืขื‘ื•ื“. ื™ืฉ ืจืง ื‘ืขื™ื” ืื—ืช ืขื ื”ืงื•ื“ ืื•ืชื” ืื ื—ื ื• ืจื•ืื™ื ื‘ืงื•ื ืกื•ืœ ื‘ื”ื•ื“ืขืช ื”ืื–ื”ืจื”:
[MobX] Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed. Tried to modify: Repo@5.items.2? 
ื”ืื–ื”ืจื” ืื•ืžืจืช ืฉื‘ื™ืฆืขื ื• ืขื“ื›ื•ืŸ ืฉืœ ืžืฉืชื ื” ืจื™ืืงื˜ื™ื‘ื™ ืžื—ื•ืฅ ืœ action. ื”ื’ื“ืจืช action ื—ืฉื•ื‘ื” ื‘ืžื•ื‘ืืงืก ื‘ื’ืœืœ ืื•ืคื˜ื™ืžื™ื–ืฆื™ื™ืช ื‘ื™ืฆื•ืขื™ื. ื‘ืชื•ืš ืคื•ื ืงืฆื™ื” ืฉืžืกื•ืžื ืช ื› action ื›ืœ ื”ืฉื™ื ื•ื™ื™ื ื‘ืžืฉืชื ื” ื”ืจื™ืืงื˜ื™ื‘ื™ ื™ื‘ื•ืฆืขื• ื‘ื˜ืจื ื–ืืงืฆื™ื” ื™ื—ื™ื“ื” ื•ืœื "ื™ืฉื•ื“ืจื•" ื”ื—ื•ืฆื” ืขื“ ืฉื” Action ืžืกืชื™ื™ื. ื‘ืœื™ action, ื›ืœ ืฉื™ื ื•ื™ ื‘ืžืฉืชื ื” ืจื™ืืงื˜ื™ื‘ื™ ืื•ื˜ื•ืžื˜ื™ืช ื™ื’ืจื•ื ืœ render ืžื—ื“ืฉ ืฉืœ ื”ืงื•ืžืคื•ื ื ื˜ื”, ื•ืื ื™ืฉ ืœื ื• 5 ืคืงื•ื“ื•ืช ืฉืžืฉื ื•ืช 5 ืžืืคื™ื™ื ื™ื ืฉื•ื ื™ื ืฉืœ ืื•ื‘ื™ืงื˜ ืจื™ืืงื˜ื™ื‘ื™ ื™ื—ื™ื“, ืื– ืงื•ืžืคื•ื ื ื˜ื” ืฉืžืกืชื›ืœืช ืขืœ ื”ืื•ื‘ื™ืงื˜ ื”ื–ื” ืชืชืจื ื“ืจ 5 ืคืขืžื™ื. ืื‘ืœ ืจื’ืข, ื”ืคื•ื ืงืฆื™ื” ืฉืœื™ fetch ื“ื•ื•ืงื ื›ืŸ ื”ื•ื’ื“ืจื” ื› action ื ื›ื•ืŸ? ื”ื ื” ื”ืงืจื™ืื” ืœ makeObservable:
makeObservable(this, {
  items: observable,
  fetch: action
});
ื›ืŸ ื˜ื•ื‘ - ื”ืคื•ื ืงืฆื™ื” fetch ื”ื™ื action, ืื‘ืœ ื”ืงื•ื“ ืฉื‘ืชื•ืš ื” then ืฉืœ ื”ื”ื‘ื˜ื—ื•ืช ื”ื•ื ื›ื‘ืจ ืœื. ื›ืœื•ืžืจ ื‘ืงืจื™ืื” ื”ื–ื•:
fetch(`${this.endpoint}/${id}`)
  .then((res) => res.json())
  .then((data) => {
    this.items[id] = {
      id,
      data,
      index: ++this.index
    };

    if (Object.keys(this.items).length > MAX_CACHE_SIZE) {
      const oldestItem = _.minBy(Object.values(this.items), (i) => i.index);
      delete this.items[oldestItem.id];
    }
  });
ืฉืชื™ ืคื•ื ืงืฆื™ื•ืช ื” Callback ืฉืžื•ืขื‘ืจื•ืช ืœืฉื ื™ ื”ื‘ืœื•ืงื™ื ืฉืœ then ื›ื‘ืจ ืื™ื ืŸ ื ื—ืฉื‘ื•ืช ื‘ืชื•ืจ action. ื›ืฉืคื•ื ืงืฆื™ื™ืช ื” Callback ื”ืฉื ื™ื” ืžืฉื ื” ืืช this.items ื–ื” ื’ื•ืจื ืœืื–ื”ืจื” ืฉืจืื™ื ื•. ื”ืคื™ืชืจื•ืŸ ื”ื•ื ืœืขื˜ื•ืฃ ืืช ื”ื—ืœืง ืฉืžืฉื ื” ืžืฉืชื ื™ื ืจื™ืืงื˜ื™ื‘ื™ื™ื ื‘ืชื•ืš ืงืจื™ืื” ืœ runInAction, ืคื•ื ืงืฆื™ื” ืฉืœ mobx ืฉืžืงื‘ืœืช ืคื•ื ืงืฆื™ื” ื•ื”ื•ืคื›ืช ืื•ืชื” ืœ action. ื”ืงื•ื“ ื”ืžืชื•ืงืŸ ื ืจืื” ื›ืš:
  fetch(id) {
    if (this.items[id]) {
      return;
    }

    fetch(`${this.endpoint}/${id}`)
      .then((res) => res.json())
      .then((data) => {
        runInAction(() => {
          this.items[id] = {
            id,
            data,
            index: ++this.index
          };

          if (Object.keys(this.items).length > MAX_CACHE_SIZE) {
            const oldestItem = _.minBy(

ToCode
1 419
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" title="objective-fog-1rmocb" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" ></iframe> ื•ืคื” ื›ื‘ืจ ื”ืงื•ื“ ื ืฉื‘ืจ. ืืชื ื™ื›ื•ืœื™ื ืœืœื—ื•ืฅ ืขืœ ื›ืคืชื•ืจ Shuffle ื•ืœืจืื•ืช ืฉื”ืจืฉื™ืžื” ืžืชืขื“ื›ื ืช, ืื‘ืœ ื›ืฉืชื ืกื• ืœืœื—ื•ืฅ ืขืœ ื›ืคืชื•ืจ ืคืœื•ืก 1 ื›ื“ื™ ืœื”ื•ืกื™ืฃ 1 ืœื›ืœ ืคืจื™ื˜ ื‘ืจืฉื™ืžื” ืื ื—ื ื• ืžืงื‘ืœื™ื ืืช ื”ื•ื“ืขืช ื”ื”ื“ืคืกื” ืžืžื•ื‘ืืงืก, ืื‘ืœ ืจื™ืืงื˜ ืœื ืžืชืขื“ื›ืŸ ื‘ืฉื™ื ื•ื™. ืžื” ืงื•ืจื” ื›ืืŸ ื•ืื™ืš ืžืชืงื ื™ื? ื ืชื—ื™ืœ ื‘ื‘ืขื™ื” ื•ื”ื™ื ื”ืคื•ื ืงืฆื™ื” RandomList:
function RandomList(props) {
  const { items, renderItem = defaultRenderItem } = props;
  return (
    <ul>
      {items.map((v, index) => (
        <li key={index}>{renderItem(v)}</li>
      ))}
    </ul>
  );
}
ื”ืคื•ื ืงืฆื™ื” ืœื ืžื•ื’ื“ืจืช ื‘ืชื•ืจ observer ื•ืœื›ืŸ ืœื ืžืงืฉื™ื‘ื” ืœืฉื™ื ื•ื™ื™ื ื‘ืžืฉืชื ื™ื ื”ืจื™ืืงื˜ื™ื‘ื™ื™ื ืฉืœื”. ืžื™ ืฉืขื•ื‘ื“ ืขื ืžื™ื“ืข ืจื™ืืงื˜ื™ื‘ื™, ืฉื–ื” ื”ืคื•ื ืงืฆื™ื” ื”ื—ื™ืฆื•ื ื™ืช App, ืžื•ื’ื“ืจ ื‘ืชื•ืจ observer ืื‘ืœ ื–ื” ืœื ืžืกืคื™ืง ื›ื™ ื”ื•ื ืžืขื‘ื™ืจ ืืช ื”ืžื™ื“ืข ื”ืจื™ืืงื˜ื™ื‘ื™ ืฉืœื• ืคื ื™ืžื”. ื”ืคืขื•ืœื” ื”ืฉื ื™ื”, shuffle, ื“ื•ื•ืงื ื›ืŸ ืขื•ื‘ื“ืช ื‘ื’ืœืœ ืฉื”ื™ื ืžืฉื ื” ืืช ื”ืžืขืจืš values ืขืฆืžื•. ื”ืงื•ืžืคื•ื ื ื˜ื” App ืžืกืชื›ืœืช ืขืœ ื”ืžืขืจืš values ื•ื›ืฉื”ื•ื ื™ื•ื—ืœืฃ ื‘ื—ื“ืฉ ื’ื ื”ื™ื ืชืชืจื ื“ืจ ืžื—ื“ืฉ. ืคืขื•ืœืช ื”ืคืœื•ืก ื”ื™ื ื”ื‘ืขื™ื™ืชื™ืช ื›ื™ ื”ื™ื ืžืฉื ื” ืืช ื”ืื™ื‘ืจื™ื ื‘ืชื•ืš ื”ืžืขืจืš, ื•ืขืœื™ื”ื ืžื™ ืฉืžืกืชื›ืœ ื–ื” ืจืง ื”ืงื•ืžืคื•ื ื ื˜ื” RandomList ื‘ืคื•ื ืงืฆื™ื™ืช ื” map ืฉื”ื™ื ืžืคืขื™ืœื”. ื”ืคื™ืชืจื•ืŸ ื”ืงืœ ื‘ืžืฆื‘ ื›ื–ื” ื”ื•ื ืœื”ืคื•ืš ืืช RandomList ืœ observer. ืื‘ืœ ืœื ืชืžื™ื“ ื–ื” ืืคืฉืจื™ ื›ื™ ืื•ืœื™ ืงื™ื‘ืœืชื ืื•ืชื” ืžืกืคืจื™ื™ืช ืงื•ื“ ื—ื™ืฆื•ื ื™ืช. ืื ืืชื ืœื ื™ื›ื•ืœื™ื ืœืฉื ื•ืช ืืช RandomList ืขืฆืžื” ื”ืคื™ืชืจื•ืŸ ื”ื™ื•ืชืจ ื’ื ืจื™ ืžื•ืจื›ื‘ ืžืฉื ื™ ื—ืœืงื™ื: 1. ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื”ืคื•ืš ืืช ื”ืงื•ื“ ืฉืœ renderItem ืœ Observer. ื–ื” ืœื ื‘ืขื™ื” ื›ื™ ื–ื” ืงื•ื“ ืฉืื ื—ื ื• ืžืขื‘ื™ืจื™ื ืžื‘ื—ื•ืฅ ืœืชื•ืš ื”ืงื•ืžืคื•ื ื ื˜ื”. 2. ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœืขื“ื›ืŸ ืืช Randomizer ื›ืš ืฉื™ืฉืžื•ืจ ืจืฉื™ืžื” ืฉืœ ืื•ื‘ื™ืงื˜ื™ื ื•ืœื ืฉืœ ืžืกืคืจื™ื. ื‘ืฆื•ืจื” ื›ื–ืืช ื”ื’ื™ืฉื” ืœืื•ื‘ื™ืงื˜ ืจื™ืืงื˜ื™ื‘ื™ ืชื—ื–ื•ืจ ืœื”ื™ื•ืช ืžืชื•ืš ืงื•ื“ ืจื™ืืงื˜ื™ื‘ื™ ื•ื›ืœ ื”ืฉื™ื ื•ื™ื™ื ื™ื•ืฆื’ื• ื›ืžื• ืฉืฆืจื™ืš ืขืœ ื”ืžืกืš. ืืคืฉืจ ืœืจืื•ืช ืืช ื”ืคื™ืชืจื•ืŸ ื‘ืงื•ื“ืกื ื“ื‘ื•ืงืก ื‘ืงื™ืฉื•ืจ: https://codesandbox.io/s/gallant-parm-p1nwgm?file=/src/App.js ืื• ืžื•ื˜ืžืข ื›ืืŸ: <iframe src="https://codesandbox.io/embed/gallant-parm-p1nwgm?fontsize=14&hidenavigation=1&theme=dark" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" title="gallant-parm-p1nwgm" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" ></iframe> ## ืžื” ืขื•ืฉื™ื ืขื ืงื•ื“ ืืกื™ื ื›ืจื•ื ื™ ืฉืžืฉื ื” ืžื™ื“ืข ืจื™ืืงื˜ื™ื‘ื™ ืื ื›ืœ ื”ืžื™ื“ืข ืฉืœื ื• ื ืฉืžืจ ื‘ืžื•ื‘ืืงืก, ืจืง ื”ื’ื™ื•ื ื™ ืœื ืกื•ืช ืœื”ืฉืชืžืฉ ื‘ื• ื’ื ื‘ืชื•ืจ ืžื ื”ืœ ืœื‘ืงืฉื•ืช ื”ืจืฉืช ืฉืœื ื•. ืœืคื ื™ ืฉื ื’ื™ืข ืœื“ื‘ืจ ืขืœ Action-ื™ื ืืกื™ื ื›ืจื•ื ื™ื™ื, ื‘ื•ืื• ื ื™ืงื— ืืช ื”ื’ื™ืฉื” ื”ื ืื™ื‘ื™ืช ื•ื ื›ืชื•ื‘ ืงื•ื“ ืืกื™ื ื›ืจื•ื ื™ ื‘ืžื•ื‘ืืงืก. ื‘ื“ื•ื’ืžื” ื”ื‘ืื” ืื ื™ ืจื•ืฆื” ืœื›ืชื•ื‘ ืžืขืจื›ืช ืฉืžืฆื™ื’ื” ืžื™ื“ืข ืžืชื•ืš swapi ื›ืœื•ืžืจ ืžื™ื“ืข ืขืœ ื“ืžื•ื™ื•ืช, ืกืจื˜ื™ื, ื—ืœืœื™ื•ืช ื•ืžื” ืœื ืžืžืœื—ืžืช ื”ื›ื•ื›ื‘ื™ื. ืื ื™ ืžืชื—ื™ืœ ืขื ืงืœืืก ืžื•ื‘ืืงืกื™ ื‘ืฉื Repo ืฉืžืกืคืง ื™ื™ืฆื•ื’ ืฆื“-ืœืงื•ื— ืœื˜ื‘ืœื”. ืœ Repo ื™ืฉ Endpoint, ืฉื–ื” ื”ื ืชื™ื‘ ื‘ืฉืจืช ืžืžื ื• ื”ื•ื ืœื•ืงื— ืืช ื”ื ืชื•ื ื™ื, ื•ืคื•ื ืงืฆื™ื” ื‘ืฉื fetch ืฉืžืงื‘ืœืช ืžื–ื”ื” ื›ืœืฉื”ื• ื•ืฉื•ืžืจืช ืืช ื”ืžื™ื“ืข ืฉืžืชืื™ื ืœื•. ื”ืจื™ืคื• ืžื•ื’ื‘ืœ ืœืฉืžื™ืจืช 10 ืคืจื™ื˜ื™ื ื•ื›ืœ ื”ืคืจื™ื˜ื™ื ื ืฉืžืจื™ื ื‘ืฆื•ืจื” ืจื™ืืงื˜ื™ื‘ื™ืช. ื–ื” ื”ืงื•ื“:
import _ from "lodash";
import { makeObservable, observable, action, runInAction } from "mobx";

const MAX_CACHE_SIZE = 10;

class Repo {
  constructor(endpoint) {
    this.endpoint = endpoint;
    this.index = 0;
    this.items = {};

    makeObservable(this, {
      items: observable,
      fetch: action
    });
  }

  fetch(id) {
    if (this.items[id]) {
      return;
    }

    fetch(`${this.endpoint}/${id}`)
      .then((res) => res.json())
      .then((data) => {
        this.items[id] = {
          id,
          data,
          index: ++this.index
        };

        if (Object.keys(this.items).length > MAX_CACHE_SIZE) {
          const oldestItem = _.minBy(Object.values(this.items), (i) => i.index);

ToCode
1 419
ื‘ื™ื•ื ืจื’ื™ืœ ื”ื™ื™ืชื™ ืžืฉืชืžืฉ ื‘ bind ืžื” constructor, ืื‘ืœ ื‘ื’ืœืœ ืฉืื ื™ ืงื•ืจื ืœ makeObservable ื’ื™ืฉื” ื–ื• ืœื ืชืขื‘ื•ื“. ื”ืคื™ืชืจื•ืŸ ื”ื•ื ืœืขื“ื›ืŸ ืืช ืžื•ื‘ืืงืก ืฉืื ื™ ืจื•ืฆื” ืœืืคืฉืจ ืœืœืงื•ื—ื•ืช ืžื—ื•ืฅ ืœืžื—ืœืงื” ืœื”ืฉืชืžืฉ ื‘ืคื•ื ืงืฆื™ื” ื•ืœืงื‘ืœ ืชืžื™ื“ ืืช ื”ืขืจืš ื”ื ื›ื•ืŸ ืฉืœ this, ื•ื–ืืช ื”ืžืฉืžืขื•ืช ืฉืœ action.bound. ื‘ื—ื–ืจื” ืœืจื™ืืงื˜, ื ื•ื›ืœ ืœื›ืชื•ื‘ ืืช ื”ืงื•ื“ ื”ื‘ื ื›ื“ื™ ืœื”ืฆื™ื’ ืฉืœื•ืฉื” ืžื•ื ื™ ืœื—ื™ืฆื•ืช ืžืกื•ื ื›ืจื ื™ื - ืœื—ื™ืฆื” ืขืœ ื”ื›ืคืชื•ืจ ื‘ื›ืœ ืื—ืช ืžื”ืงื•ืžืคื•ื ื ื˜ื•ืช ืชืขื“ื›ืŸ ืืช ื”ืขืจืš ื‘ืฉืชื™ ื”ืื—ืจื•ืช:
import "./styles.css";
import { observer } from "mobx-react-lite";
import counter from "./mobx/counter";

const Counter = observer(function Counter() {
  return (
    <div>
      <p>Value = {counter.value}</p>
      <button onClick={counter.click}>+1</button>
    </div>
  );
});

export default function App() {
  return (
    <div className="App">
      <Counter />
      <Counter />
      <Counter />
    </div>
  );
}
ื•ื’ื ืืช ื”ื“ืžื• ื”ื–ื” ื”ืขืœื™ืชื™ ืœืงื•ื“ืกื ื“ื‘ื•ืงืก ื•ื™ื›ื•ืœื™ื ืœืจืื•ืช ืื•ืชื• ื‘ืงื™ืฉื•ืจ: https://codesandbox.io/s/gifted-ride-qnoj92?file=/src/App.js ืื• ื›ืืŸ ืœืžื˜ื”: <iframe src="https://codesandbox.io/embed/gifted-ride-qnoj92?fontsize=14&hidenavigation=1&theme=dark" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" title="gifted-ride-qnoj92" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" ></iframe> ## ื”ื‘ืขื™ื” ืขื ืชื‘ื ื™ืช Render Props ื•ืื™ืš ืœื”ืชืื™ื ืื•ืชื” ืœืขื‘ื•ื“ื” ืจื™ืืงื˜ื™ื‘ื™ืช ืจื•ื‘ ื”ื“ื‘ืจื™ื ืฉืื ื—ื ื• ื”ื•ืœื›ื™ื ืœื›ืชื•ื‘ ื‘ืจื™ืืงื˜ ื™ืขื‘ื“ื• ื‘ืœื™ ื‘ืขื™ื•ืช ืžื™ื•ื—ื“ื•ืช. ืฉื™ื˜ืช ื”ืขื‘ื•ื“ื” ืขื ืจื™ืืงื˜ ื•ืžื•ื‘ืืงืก ืชื”ื™ื” ืœื›ืชื•ื‘ ืงื•ื“ื ืืช ื›ืœ ื”ืœื•ื’ื™ืงื” ื•ื”ืกื˜ื™ื™ื˜ ื”ื’ืœื•ื‘ืืœื™ ื‘ืชื•ืš ืžื—ืœืงื•ืช ืžื•ื‘ืืงืก, ื•ืื—ืจ ื›ืš ืœื—ื‘ืจ ืœื–ื” ืžืžืฉืง ืžืฉืชืžืฉ ื‘ืืžืฆืขื•ืช ืจื™ืืงื˜. ืื‘ืœ ื›ืŸ ื™ืฉ ืžืกืคืจ ืžืงืจื™ื ืœื ืื™ื ื˜ื•ืื™ื˜ื™ื‘ื™ื™ื ื‘ืขื‘ื•ื“ื” ืขื ืžื•ื‘ืืงืก ื•ืขืœื™ื”ื ืื ื™ ืจื•ืฆื” ืœื“ื‘ืจ ื‘ื—ืœืงื™ื ื”ื‘ืื™ื ืฉืœ ืžื“ืจื™ืš ื–ื”. ื”ืžื•ืงืฉ ื”ืจืืฉื•ืŸ ื‘ืขื‘ื•ื“ื” ืขื ืžื•ื‘ืืงืก ื•ืจื™ืืงื˜ ื”ื•ื ืชื‘ื ื™ืช Render Props. ื‘ืชื‘ื ื™ืช ื–ื• ื™ืฉ ืœื ื• ืงื•ืžืคื•ื ื ื˜ืช ืจื™ืืงื˜ ืฉืžืงื‘ืœืช ื—ืœืง ืžื”ืœื•ื’ื™ืงื” ืฉืœ ืื™ืš ืœื”ืฆื™ื’ ืžื™ื“ืข ืžืงื•ืžืคื•ื ื ื˜ื” ืื—ืจืช - ืœืžืฉืœ ืงื•ืžืคื•ื ื ื˜ื” ืฉืœ ืจืฉื™ืžื” ืฉืžืงื‘ืœืช ื‘ืชื•ืจ ืคืจืžื˜ืจ ืคื•ื ืงืฆื™ื” ืฉืื—ืจืื™ืช ืขืœ ืจื™ื ื“ื•ืจ ืคืจื™ื˜ ื‘ืจืฉื™ืžื”. ืชื‘ื ื™ืช Render Props ื”ื™ื ืžื‘ืœื‘ืœืช ื›ื™ ื”ืงื•ื“ ืฉืžื’ื™ืข ืžื‘ื—ื•ืฅ, ื›ื‘ืจื™ืจืช ืžื—ื“ืœ, ืœื ืžื•ื’ื“ืจ ื‘ืชื•ืจ Observer ื•ืœื›ืŸ ืœืคืขืžื™ื ืฉื™ื ื•ื™ื™ื ืœื ื™ื™ืงืœื˜ื•. ื‘ื•ืื• ื ืžื—ื™ืฉ ืืช ื”ื‘ืื’ ืขื ืชื•ื›ื ื™ืช ืงื˜ื ื” ืœื ื™ื”ื•ืœ ืจืฉื™ืžืช ืžืกืคืจื™ื ืืงืจืื™ื™ื. ืชื—ื™ืœื” ืื ื™ ื›ื•ืชื‘ ืžื—ืœืงื” ื‘ืžื•ื‘ืืงืก ืฉื™ื•ื“ืขืช ืœื™ื™ืฆืจ ื•ืœืฉืžื•ืจ 10 ืžืกืคืจื™ื ืืงืจืื™ื™ื:
import _ from "lodash";
import { makeObservable, observable, action } from "mobx";

class Randomizer {
  constructor() {
    this.shuffle();

    makeObservable(this, {
      values: observable,
      shuffle: action.bound,
      incAll: action.bound
    });
  }

  shuffle() {
    this.values = _.range(10).map((x) => _.random(1, 100));
  }

  incAll() {
    for (let i = 0; i < this.values.length; i++) {
      this.values[i] += 1;
    }
    console.log(this.values);
  }
}

const randomizer = new Randomizer();
export default randomizer;
ืขื›ืฉื™ื• ืื ื™ ืžืžืฉื™ืš ืœื—ื‘ืจ ืื•ืชื” ืœืงื•ืžืคื•ื ื ื˜ื•ืช ืจื™ืืงื˜ ืขื ื”ืงื•ื“ ื”ื‘ื ื‘ App.js:
import "./styles.css";
import { observer, Observer } from "mobx-react-lite";
import randomizer from "./mobx/randomizer";

function defaultRenderItem(value) {
  return <span>{value}</span>;
}

function RandomList(props) {
  const { items, renderItem = defaultRenderItem } = props;
  return (
    <ul>
      {items.map((v, index) => (
        <li key={index}>{renderItem(v)}</li>
      ))}
    </ul>
  );
}

export default observer(function App() {
  return (
    <div className="App">
      <button onClick={randomizer.shuffle}>Shuffle</button>
      <button onClick={randomizer.incAll}>+1 </button>
      <RandomList
        items={randomizer.values}
        renderItem={(item) => <span>{item}</span>}
      />
    </div>
  );
});
ืืคืฉืจ ืœืจืื•ืช ื’ื ืื•ืชื• ืœื™ื™ื‘ ื‘ืงื•ื“ืกื ื“ื‘ื•ืงืก ื›ืืŸ: <iframe src="https://codesandbox.io/embed/objective-fog-1rmocb?fontsize=14&hidenavigation=1&theme=dark"