【问题标题】:How to map over 2 Array in React and render to Table如何在 React 中映射超过 2 个数组并渲染到表
【发布时间】:2021-12-27 20:37:19
【问题描述】:

我正在创建一个股票应用程序,它允许用户通过调用 Stock API 来搜索股票价格并搜索任何股票并取回其价格。

我将价格存储在表格中,但是我也希望能够将用户输入的内容存储到表格中。

我的策略是将用户的搜索输入存储到数组“symbolArray”中,将 api 信息存储到“dataArray”中。”

所以这是我的问题。我能够映射“dataArray”并将其呈现到表格中。但是我需要映射“symbolArray”并将其渲染到已经从“数据数组”渲染项目的表中。

这就是我目前所拥有的

const Quotes = ()=> {

//I call their states
const [symbolArray, setSymbolArray] = useState([])
const [dataArray, setDataArray] = useState([])


//this function stores, and calls the api data that the user searches for


function getData() {

  fetch(url)
        .then(res => res.json())
        .then(data =>{
          
            dataArray.push(data)
            
        })
        
}

// this is also activated when the user searchs. their input is pushed to the array of stock ticker symbols

const addingStuff = ()=> {
  symbolArray.push(input)

}


return (

<>

{/* here a user searches for stock */}

<div class="input-group">
                <input id="searchBar" type="search" class="form-control rounded search-bar" placeholder="Enter Ticker Symbol" aria-label="Search"
                   aria-describedby="search-addon" value={input} onInput={e => setInput(e.target.value)} />
                <button type="button" class="searchButton btn p-2  bg-succ" id="searchButton" onClick={()=> {getData(); addingStuff(); }}>Quote This Stock</button>
              </div>

{/* here is my table */}
<table class='table'>
                  <thead>
                    <tr>
{/*  table  headers*/}
                      <th scope='col'>Symbol</th>
                      <th scope='col'>Current Price</th>
                      <th scope='col'>Day High</th>
                      <th scope='col'>Day Low</th>
                      <th scope='col'>Price Change</th>
                      <th scope='col'>Open Price</th>
                      <th scope='col'>Percentage Change</th>
                      <th scope='col'>Previous Close</th>
                    </tr>
                  </thead>
                  <tbody>

{/* i call the function that gets and stores the data */}

                  {getData ? 
                    dataArray.map((stock, index) => {
                      const {c, d, dp, h, l, o, pc} = stock;
                      return (
                        <tr key={index}>

{/* here is the issue where the 2 arrays clash  */}
                         <th scope='row'>{symbolArray.map((symbol, i) => { return i})}</th>
                          <td>{c}</td>
                          <td>{d}</td>
                          <td>{dp}</td>
                          <td>{h}</td>
                          <td>{l}</td>
                          <td>{o}</td>
                          <td>{pc}</td>
                        </tr>
                      )
                    })
  
                     : null }


</>

}



【问题讨论】:

  • 你忘记了addingStuff中的input参数,它应该是const addingStuff = input =&gt; ...
  • 您好 Ameer,非常感谢您的评论!不幸的是,当我继续搜索股票时,将数据从我的数组中推出并让字段变为空白。不过还是谢谢!仍然会投票回复

标签: javascript reactjs jsx


【解决方案1】:

当您使用像 React 这样的库/框架时,最好将演示文稿与控件分离。在您的情况下,这意味着:

  • 表格是演示文稿。它应该不知道数据来自哪里(来自symbolArray 或来自dataArray - 或两者兼有)。
  • symbolArraydataArray 和它们的联合是控制。这不需要“知道”数据的呈现方式(可以是有序/无序列表、表格或显示为卡片元素的简单数据迭代器)。

考虑到这一点,我认为您应该将解决方案分为两部分:

  • 一部分负责获取和处理数据
  • 另一部分负责在表格中显示一组数据。

这是一个执行此操作的 sn-p:

const { useState, useEffect } = React

// custom hook for mocking API data
const useTypicode = () => {
  const [response, setResponse] = useState(null);

  // only runs once
  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(res => res.json())
      .then(json => {
        setResponse(() => json.map(({id, name, username, email}) => ({id, name, username, email})))
      })
  }, []);

  return response;
};

// AddUser doesn't know what is happening when the
// button is clicked: only sends the current state
// as an argument for the function it received
// in props
const AddUser = (props) => {
  const [name, setName] = useState(null)
  const [userName, setUserName] = useState(null)
  const [email, setEmail] = useState(null)
  
  return (
    <div>
      Name: <input type="text" onInput={(e) => setName(e.target.value)}/><br />
      Username: <input type="text" onInput={(e) => setUserName(e.target.value)}/><br />
      Email: <input type="text" onInput={(e) => setEmail(e.target.value)}/><br />
      <button
        onClick={() => props.addUser({name, userName, email})}
      >
        ADD USER +
      </button>
    </div>
  )
}

// Table doesn't "know" where the data comes from
// API, user created - doesn't matter
const Table = (props) => {
  const headers = Object.keys(props.userList[0])
  return (
    <table>
      <thead>
        <tr>
          {
            headers.map(header => <th key={header}>{header}</th>)
          }
        </tr>
      </thead>
      <tbody>
        {
          props.userList.map(user => <tr key={user.id}>{Object.values(user).map((val, i) => <td key={user.id + i}>{val}</td>)}</tr>)
        }
      </tbody>
    </table>
  )
}

// App doesn't know how the custom data is being
// entered or how it is displayed - only knows
// how to update the two lists it handles and
// where to pass them on
const App = () => {
  const apiUsers = useTypicode()
  const [users, setUsers] = useState([])
  
  const addUser = (userData) => {
    setUsers(prevState => [
      ...prevState,
      {
        id: Date.now(),
        ...userData
      }
    ])
  }
  
  return (
    <div>
      <AddUser
        addUser={(userData) => addUser(userData)}
      /><br />
      {
        apiUsers &&
          <Table
            userList={[...apiUsers, ...users]}
          />
      }
      
    </div>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="root"></div>

抱歉,sn-p 中有一些“不好的做法”(例如在 AddUser 中的 JSX 元素中定义函数),但基本逻辑是我想说明的:不要将 HTML 表视为存储任何东西的实体。不,HTML 表格只显示您提供的内容。在 JS 中“播放”数据(合并不同的源、按键/值过滤、排序等),并且表示(表格)应该更新(因为它提供了一组可以显示的新数据)。这是反应性。

【讨论】:

  • 非常感谢穆卡的回复。我是新手,我能够掌握的概念,但是实施将需要我一分钟哈哈。当我尝试剖析这段代码并将其拆开时,我会假设这是答案。谢谢!!!
  • @user16645351 我希望这真的有帮助 - 当然,您需要修改/更新/升级它(如用户输入清理),但这是一种从 API 合并数据的方法用户。
猜你喜欢
  • 1970-01-01
  • 2021-02-22
  • 2014-10-29
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 2021-05-29
  • 1970-01-01
相关资源
最近更新 更多