React は props を報告します。「関数」は関数ではありません
P粉475315142
2023-09-04 10:38:59
<p>初めてのオンライン ストアを作成しているのですが、問題が発生しました。製品カード データを含む偽の API を作成し、<code>axios.get</code> を使用してそれらを取得し、状態に追加すると、「props.addCardData は関数ではありません」というメッセージが表示されます。<code>axios.get</code> を追加するまでは、すべて正常に動作すると言わざるを得ません。他の関数は、関数 <code>addCardData</code> と同じ方法で使用します。つまり、<code>mapDispatchToProps</code> を使用し、<code>props.addCardData</code> を使用しました。 - I <code>axios.get</code> やその他のリクエストでは使用しません)。以前はどの機能も問題なく使用できました。 </p>
<p><code>axios.get</code> 経由でデータを取得し、アクション クリエーターをパラメータとしてディスパッチを呼び出す関数をカード コンテナから呼び出す予定です。 </p>
<p>「未定義のプロパティを読み取ることができません ('addCardData' を読み取ります)」も見つかりました。</p>
<p>以下に、問題の影響を受けるコード部分を示します (どのコードがどの要素に適用されるかを示します)</p>
<p>これは Cards コンポーネントのコードです (ここではインポートを追加しませんでしたが、インポートはすべてあります): </p>
<pre class="brush:php;toolbar:false;">const Cards = (props) => {
axios.get('https://mocki.io/v1/8cb0f160-92f7-4cf8-a6c1-f63690df514e')
.then(応答 => {
props.addCardData(response.data)
})
letcardArray = Object.keys(props.cardsData).map(card => (
<オファーカード
key={カード.id}
bg={props.cardsData[カード].bg}
id={props.cardsData[カード].tagId}
title={props.cardsData[カード].title}
text={props.cardsData[カード].text}
ボタン={
<容器液>
<行クラス名={'row-cols-auto'}>
{props.cardsData[カード].button.map(button => (
<カードボタン
key={ボタン.id}
リンク={ボタン.リンク}
type={ボタン.タイプ}
class={ボタン.クラス}
名前={ボタン.名前}
/>
))}
</行>
</コンテナ>
}
/>
))
戻る (
<容器液>
<img src={'./backgrounds/bestoffers.png'} alt={'ベストオファー'} className={'img-fluid imgTab'} />
<Row xs={1} md={2} id={'cards-row'} className={'border border-4 g-3'}>
{/*row-cols-* - 行内のカードの量を設定してカードの幅を設定します*/}
{カード配列}
</行>
</コンテナ>
)
}
デフォルトのカードをエクスポート</pre>
<p>これは <code>CardsContainer</code> のコードです: </p>
<pre class="lang-js prettyprint-override"><code>const mapStateToProps = (state) => {
戻る {
カードデータ: state.homePage.cardsData
}
}
const mapDispatchToProps = (ディスパッチ) => {
戻る {
addCardData: (データ) => {
ディスパッチ(addCardsData(データ))
}
}
}
const CardsContainer = connect(mapStateToProps, mapDispatchToProps)(Cards);
デフォルトの CardsContainer をエクスポートする
</code></pre>
<p>これはリデューサー内のコードです: </p>
<pre class="lang-js prettyprint-override"><code>...
homePageCardsData = 'ホームページ-カード-データ'
InitialState = {...} - 「cardsData: {}」が含まれます。
const homePageReducer = (state =InitialState, action) => {
stateCopy を実行します。
スイッチ (アクション.タイプ) {
ケース homePageCardsData: {
stateCopy = {...状態、カードデータ: action.data}
壊す
}
...
デフォルト: 状態を返します。
}
状態コピーを返します。
...... - ここにいくつかの機能があります (知る必要はありません)
}
エクスポート const addCardsData = (データ) => ({
タイプ: homePageCardsData、
データ: データ
})
</code></pre>
<p>次のようなことを試してみると: </p>
<pre class="lang-js prettyprint-override"><code>const addCard = props.addCardData
axios.get('https://mocki.io/v1/8cb0f160-92f7-4cf8-a6c1-f63690df514e')
.then(応答 => {
addCard(response.data)
})
</code></pre>
<p>ローカルホスト (ホームページ上!!) で遅れが発生しており、すべてのレンダリングの開始が遅く、70% の確率でカード ブロックがレンダリングされません。他の場合には、しばらくしてからレンダリングされる可能性があります (まれな可能性)。メニューのテスト中に変更を確認する必要があるため、AdminPanel ページで <code>Cards</code> をレンダリングしていると、「TypeError: addCard is not a function.」というメッセージが表示されます。</p>
<p>このコードをコンポーネントから削除すると、すべて正常に動作します。 </p>
<p>「デバッガー」を使用し、それを <code>homePageCardsData</code> に配置したことも言わなければなりません。スクリプトはデバッガー上で停止します (<code>StateCopy</code> の後、<code>break</code> の前)。これは、スクリプトが正しく、<code>dispatch</code> が機能し、<code>homePageCardsData</code> のケースに入ることができることを意味します。 </p>
問題は
Cards
コンポーネントにあり、コンポーネントの関数本体で直接、意図しない副作用として Axios GET リクエストが行われます。これにより、レンダリング ループが作成される可能性が高く、少なくともCards
がレンダリングされるたびに GET リクエストが作成されます。このコードを
###例:### リーリーuseEffect
フックに移動して、コンポーネントのインストール後に呼び出されるようにします。かなり古い Redux コードを使用していますが、
useDispatchおよび
リーリーuseSelector
フックがその使用法を置き換えたため、通常はconnect
上位コンポーネントを使用しなくなりました。現在の標準は、Redux-Toolkit
を使用することです。これにより、記述する必要があるボイラープレートの量が
does 削減されます。 以下は更新提案の例です:reducer コード、オペレーション タイプ、オペレーション クリエーター... すべてが 1 つの状態スライスに置き換えられます。
リーリー