Witam.

Otóż mam kod renderujący na podstawie typu orderbook giełdy kryptowalut. Ma to działać tak, że w inpucie amount np. gdy chcemy kupić 1000btc ma nam podświetlać ilość transakcji po stronie sprzedających, których łączna wartość daje tyle ile chcemy kupić.

Wpisujemy w inpucie dla komponentu instancji ask, ma podświetlić transakcje dla bid i na odwrót.

Z komponentu nadrzędnego jakim jest OrderbookController.js dane przychodzą prawidłowo czy to przez propsa czy też context, ale mniejsza o to. komponent podrzędny OrderbookTransactions.js porównuje i zwraca do propsa kolejnego komponentu, true lub false i na tej podstawie komponent wie czy ma być podświetlony czy nie.

Brzmi prosto.

Schody pojawiają się gdy do OrderbookTransactions.js dane przychodzą dynamicznie. Nie chcą się podświetlić za cholerę. Przerabiałem różne przypadki z użyciem stanu itd.

Jak wklepie dane na sztywno w w komponencie nadrzędnym do propsa czyli np. tak

<OrderbookTransactions type={type} arrayOfPriceForSelector={[{price: 1.00, type: 'bid', price: 1.12, type: bid}} />

to obydwie instancje OrderbookTransactions dla bid i ask wyrenderują się i wszystko od strzała jest podświetlone tak jak chcę, a jezeli dane pochodzą ze stanu lokalnego komponentu OrderbookController.js i dynamicznie są aktualizowane to nie podświetla się nic.

Z resztą co ja będę mówił, rzućcie okiem na obydwa komponenty i pomyślcie jak to można byłoby rozwiązać wspólnymi siłami.

Komponent nadrzędny OrderbookController.js

import { createContext, useEffect, useState } from 'react'
import Input from 'components/atoms/Input/Input.js'
import { StyledParahraph } from 'components/atoms/StyledParahraph/StyledParahraph.js'
import { StyledPrice } from 'components/atoms/StyledPrice/StyledPrice.js'
import Button from 'components/atoms/Button/Button.js'
import ToggleSwitch from 'components/atoms/ToggleSwitch/ToggleSwitch.js'
import { Wrapper, TypeText, OrderFieldsWrapper, FieldItem, SpanOfField, WrapperControlPanel } from './OrderbookController.styles.js'
 
import OrderbookTransactions from 'components/organisms/OrderbookTransactions/OrderbookTransactions.js'
import useOrderbookComposition from 'hooks/useOrderbookComposition.js'
import { v4 as uuidv4 } from 'uuid'
import useOrderbookTransactions from 'hooks/useOrderbookTransactions.js'
import { activeTransactionsAction } from 'actions/activeTransactions.js'
import { useDispatch, useSelector } from 'react-redux'
import valuePerEachOrder from 'helpers/ValuePerEachOrder.js'
 
export const PriceRangeSelectContext = createContext([])
 
const OrderbookController = ({ type }) => {
  const [arrayOfPriceForSelector, setArrayOfPriceForSelector] = useState([])
  const dispatch = useDispatch()
 
  const { handleInputChange, inputValues, config } = useOrderbookComposition()
  const { currency, symbol, pair } = config
 
  const { createNewOffer, fastTransactions, groupAndSortTransactions } = useOrderbookTransactions(type === "bid" ? "ask" : "bid", pair)
 
  const { user: { _id: userId } } = useSelector(({ user }) => ({ user }))
  const { user: { accountBalance }} = useSelector(({ user }) => ({ user }))
  const requiredAmount = 1
 
  const handleAddOffer = (type) => {
     
    const { price, amount } = inputValues
    const txId = uuidv4()
    if((amount * price) > accountBalance) {
      console.log(`Masz za mało środków. Stan twojego konta to ${accountBalance}`)
      return
    }
    createNewOffer({ price, amount: amount.replace(',', '.'), pair, type, txId, userId })
    dispatch(activeTransactionsAction({ txId, price, amount, pair, type, progress: 28 }))
 
  }
 
  const checkSufficientBalanceForTransaction  = () => {
   
    const transactions = valuePerEachOrder(groupAndSortTransactions)
 
      let summaryValueOfRequiredTransactions = 0
       
        for(let value of transactions) {
          for(let price in value) {
            summaryValueOfRequiredTransactions += requiredAmount * price
            if(summaryValueOfRequiredTransactions <= accountBalance && value[price] >= requiredAmount) {
              return true
            } else {
              console.log('Twoje saldo jest mniejsze niż wartość twojego zamówienia, doładuj swoje konto.')
            }
          }
        }
  }
   
  const handlePriceRangeSelect = (e) => {
    const tempArr = []
    let totalAmount = 0
    let remainingAmount = requiredAmount
    const transactions = valuePerEachOrder(groupAndSortTransactions)
    outerLoop:
      for (let value of transactions) {
        for (let price in value) {
          totalAmount += value[price]
          tempArr.push({price, type: type === 'bid' ? 'ask' : 'bid'})
          if(totalAmount >= requiredAmount) {
              break outerLoop;
          }
        }
    }
    setArrayOfPriceForSelector(tempArr)
  }  
 
  const handleFastTransaction = () => {
 
    if(checkSufficientBalanceForTransaction()) {
      fastTransactions(type, pair, requiredAmount, null, null, accountBalance)
    }
 
  }
 
  return (
      <Wrapper>
 
        <TypeText>{type.toUpperCase()}</TypeText>
          <OrderFieldsWrapper>
            <FieldItem>
              <StyledParahraph>Kurs {currency}</StyledParahraph>
              <Input type="number" name="price" onChange={handleInputChange} />
            </FieldItem>
             
              <SpanOfField>x</SpanOfField>
            <FieldItem>
              <StyledParahraph>Ilość {symbol}</StyledParahraph>
              <Input type="number" name="amount" onChange={(e) => {
                handleInputChange(e)
                handlePriceRangeSelect(e)
              }} />
            </FieldItem>
 
              <SpanOfField>=</SpanOfField>
            <FieldItem>
              <StyledParahraph>Wartość {currency}</StyledParahraph>
              <Input type="number" name="value" value={inputValues.totalValue} readOnly />
            </FieldItem>
 
          </OrderFieldsWrapper>
 
          <OrderFieldsWrapper>
 
            <WrapperControlPanel>
              <ToggleSwitch name="Hidden" />
              <ToggleSwitch name="Post only" />
              <ToggleSwitch name="Wall" />
            </WrapperControlPanel>
 
            <WrapperControlPanel>
              <StyledParahraph>Otrzymasz</StyledParahraph>
              <StyledPrice>{inputValues.totalAmount || 0}</StyledPrice>
            </WrapperControlPanel>
             
            <WrapperControlPanel>
              <Button onClick={() => handleFastTransaction()} disabled={!inputValues.isFilled}>{type === 'bid' ? 'FAST BUY' : 'FAST SELL'}</Button>
            </WrapperControlPanel>
            <WrapperControlPanel>
              <Button onClick={() => handleAddOffer(type)} disabled={!inputValues.isFilled}>{type === 'bid' ? 'BUY' : 'SELL'}</Button>
            </WrapperControlPanel>
 
          </OrderFieldsWrapper>
 
          <OrderbookTransactions type={type} arrayOfPriceForSelector={arrayOfPriceForSelector} />
 
        </Wrapper>
  )
 
}
 
export default OrderbookController
import DynamicListWrapper from 'components/atoms/DynamicListWrapper/DynamicListWrapper'
import styled from 'styled-components'
import StyledP from 'components/atoms/ListText/ListText.js'
import useOrderbookTransactions from 'hooks/useOrderbookTransactions.js'
import { useCryptoConfig } from 'hooks/useCryptoConfig.js'
import { useEffect, useContext, useState } from 'react'
import { PriceRangeSelectContext } from 'components/molecules/OrderbookController/OrderbookController.js'
 
const Wrapper = styled.div`
 
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 5px 10px;
  background-color: rgba(255, 255, 255, .45);
  background-image: ${({ theme }) => theme.gradient.white };
 
  border-radius: 10px;
  box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.05);
  overflow-y: scroll;
 
`
 
const OrderbookTransactions = ({ type, arrayOfPriceForSelector }) => {
 
  const [highlightedItems, setHighlightedItems] = useState([])
  console.log(arrayOfPriceForSelector)
   
  const handleCheckHighlight = (item) => {
    return arrayOfPriceForSelector.some((tx) => {
      return item.type === tx.type && item.price == tx.price
    })
  }
 
  const { pair } = useCryptoConfig().config
  const { groupAndSortTransactions } = useOrderbookTransactions(type, pair)
  const progress = 50
  console.log(groupAndSortTransactions)
  return (
    <Wrapper>
      {groupAndSortTransactions.map((item) => (
        <DynamicListWrapper key={item._id} priceRangeSelect={handleCheckHighlight(item)} isOrderbook={true} progress={progress}>
        <StyledP>{item.price}</StyledP>
        <StyledP>{item.amount.toFixed(8)}</StyledP>
        <StyledP>{(item.price * item.amount).toFixed(2)}</StyledP>
        <StyledP>54%</StyledP>
        </DynamicListWrapper>
        ))}
    </Wrapper>
  )
}
 
export default OrderbookTransactions;

Oczywiście wiem, że kod wymaga zrefaktorowania i poprawek, ale nie o to tutaj teraz chodzi.