我正在通過將一些組件分解成更小的部分來清理我的第一個專案中的代碼,但我正在努力尋找將函式從一個組件傳遞到另一個組件的最佳實踐。還有可能我只是把這一切都搞錯了!任何建議表示贊賞。下面是我希望能夠在多個組件中使用的函式的代碼ScryfallQuery,在這個特定的實體中,我試圖將它傳遞給FileHandler當前呈現以下錯誤的組件:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'ScryfallQuery')
at fileHandler.js:50:1
at Array.forEach (<anonymous>)
at updateCards (fileHandler.js:43:1)
at fileHandler.js:67:1
at invokePassiveEffectCreate (react-dom.development.js:23487:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1)
at invokeGuardedCallback (react-dom.development.js:4056:1)
at flushPassiveEffectsImpl (react-dom.development.js:23574:1)
at unstable_runWithPriority (scheduler.development.js:468:1)
如果有人能給我指出正確的文獻,那也會有幫助。此處的反應檔案https://reactjs.org/docs/faq-functions.html似乎沒有正確的方法來使用我手頭的語法傳遞函式(也許這就是問題?)。我仍在學習 React(和 js!),所以這里可能有一些明顯的東西我錯過了。
但重申一下,我正在尋找將函式傳遞給多個組件的最佳方法,在這種情況下,我的 API 查詢將傳遞給多個組件。
這是我的 App.js 代碼:
import {useState, useEffect} from 'react'
import './styles/App.css';
import FileHandler from './Components/fileHandler';
import ImagePreviewer from './Components/ImagePreviewer';
import { Header } from './Components/Header';
import { Comparison } from './Components/Comparison';
import {ScryfallQuery} from './Components/ScryfallQuery';
function App() {
const [cardInput, setCardInput] = useState([]);
const [cards, setCards] = useState([]);
const [previewCard, setPreviewCard] = useState([]);
const [comparisonCard, setComparisonCard] = useState([]);
return (
<div className="container">
{/* <GlobalState> */}
<Header />
{cards && <Comparison comparison={comparisonCard} setComparisonCard={setComparisonCard}/>}
<div className="row" id="table-main">
<div className="col-3">
<ImagePreviewer previewCard={previewCard} />
</div>
<div className="col-9">
<FileHandler
cardInput={cardInput}
setCardInput={setCardInput}
previewCard={previewCard}
setPreviewCard={setPreviewCard}
cards={cards}
setCards={setCards}
scryfallQuery={ScryfallQuery}
/>
</div>
</div>
{/*</GlobalState> */}
</div>
);
}
export default App;
這是包含該功能的組件的代碼:
export const ScryfallQuery = () => {
/*collection query function for more info read
here: https://scryfall.com/docs/api/cards */
const queryString = `https://api.scryfall.com/cards/collection`;
const queryStringified = JSON.stringify(query);
return fetch(queryString, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: queryStringified
}).then((res, err) => {
if (res) return res.json();
if (err) return new Error("Error: ", err);
});
/* scryfall api accepts maximum 75 card query,
batches query in 75 increments */
function sliceIntoBatches(arr, batchSize) {;
const batchArr = []
for (let i = 0; i < arr.length; i = batchSize) {
const batch = arr.slice(i, i batchSize);
batchArr.push(batch);
}
return batchArr;
};
}
最后是我將函式傳遞到的檔案的代碼:
import {useState, useEffect} from 'react';
import { Card } from './Card.js';
export const FileHandler = ({
cardInput, setCardInput,
cards, setCards,
previewCard, setPreviewCard,
ScryfallQuery
}) => {
const reader = new FileReader();
reader.addEventListener('load', function(){
const allCards = this.result.split(/\r?\n/g);
setCardInput(allCards)
});
/////////////////////////////////////////////////////////////////
/* scryfall api accepts maximum 75 card query,
batches query in 75 increments */
function sliceIntoBatches(arr, batchSize) {;
const batchArr = []
for (let i = 0; i < arr.length; i = batchSize) {
const batch = arr.slice(i, i batchSize);
batchArr.push(batch);
}
return batchArr;
}
/////////////////////////////////////////////////////////////////
const parseInput = (e) => {
e.preventDefault();
setCardInput([]);
reader.readAsText(document.getElementById('input').files[0])
}
const updateCards = () => {
let response;
const cardBatches = sliceIntoBatches(cardInput, 75);
cardBatches.forEach(async (cardBatch) => {
const queryArray = cardBatch.filter(cardName => cardName !== '').map(cardName => {
return {
name: cardName
}
});
response = await this.ScryfallQuery({ identifiers: queryArray });
if (response) {
console.log("response", response);
if (response.data.length > 0) {
console.log("second check", cards)
const newCards = [...cards, ...response.data];
setCards(newCards);
} else if (response.not_found.length > 0 || response.data.length <= 0) {
console.error("Cards not found: ", response.not_found);
}}
});
}
useEffect(() => {
console.log("loading");
if (cardInput.length > 0 && cards.length === 0) {
updateCards();
}
}, [cardInput]);
/////////////////////////////////////////////////////////////////
function scryfallCollectionQuery(query) {
const queryString = `https://api.scryfall.com/cards/collection`;
const queryStringified = JSON.stringify(query);
return fetch(queryString, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: queryStringified
}).then((res, err) => {
if (res) return res.json();
if (err) return new Error("Error: ", err);
});
}
/////////////////////////////////////////////////////////////////
return(
<div className="App">
<h1>Submit a .txt file of cards! </h1>
<form target="_self" onSubmit={parseInput}>
<input type="file" id="input" />
<button id="submit">Submit</button>
<pre id="preReader"></pre>
</form>
{cards &&
<table id="table-head">
<tbody>
<tr>
<td id="card-number-title">#</td>
<td id="card-name-title">Card Name</td>
<td id="card-data-title">Colors</td>
<td id="card-data-title">Rarity</td>
<td id="card-data-title">ELO</td>
</tr>
</tbody>
</table> }
{cards && cards.map(card =>
<Card
card={card}
setPreviewCard={setPreviewCard} />
)}
</div>
)
}
export default FileHandler;
uj5u.com熱心網友回復:
你忘了匯入ScryfallQueryApp.js 嗎?
uj5u.com熱心網友回復:
如果您想將功能從父母傳遞給孩子,您必須使用道具
例子 :
const parent = () =>{
const handleconsolelog = () =>{
console.log("hi")
}
return (
<children handleconsolelog={handleconsolelog}
)
}
然后在孩子們:
const childeren= ({handleconsolelog}) =>{
return (
<button onClick={handleconsolelog} />
)
}
uj5u.com熱心網友回復:
您將對該函式的參考作為scryfallQueryprop (使用小寫字母s)傳遞。
<FileHandler
cardInput={cardInput}
setCardInput={setCardInput}
previewCard={previewCard}
setPreviewCard={setPreviewCard}
cards={cards}
setCards={setCards}
scryfallQuery={ScryfallQuery}
/>
然后在里面FileHandler你嘗試使用大寫S:
export const FileHandler = ({
cardInput, setCardInput,
cards, setCards,
previewCard, setPreviewCard,
ScryfallQuery
})
為什么你this在這里使用:
response = await this.ScryfallQuery({ identifiers: queryArray });
我不知道這些是否都是錯誤,但是您的代碼一團糟,很難閱讀。最好只獲得相關的代碼片段。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/494774.html
標籤:javascript 反应
