【发布时间】:2020-01-11 16:59:45
【问题描述】:
我正在构建一个简单的电话簿来配合赫尔辛基大学的 FullstackOpen 课程。下面代码中的日志显示我的“filterBy”状态始终是一个渲染,而且我的contacts.filter也收到错误,即“contact.name.toUpperCase”不是一个函数。所以我想我有两个问题。
-
我什至可以在不使用类组件的情况下做他们想让我做的事情吗?他们还没有在课程中介绍它们,所以我假设是的。但是我想我曾经在教程中听说过,当您需要状态同步时必须使用类组件(例如,使用输入来过滤屏幕上显示的对象数组)。但我无法让 filterBy 状态实际上与过滤器输入中的内容同步。
-
我知道我的行以“const contactsToShow ...”开头可能是一种不太理想的方式来做到这一点,如果有功能的话。怎样才能做到最好?
代码:
import React, { useState } from 'react'
import Contact from './components/Contact'
const App = () => {
const [contacts, setContacts] = useState([
{ name:'Guy Fieri', number: '020-4837473'},
{ name:'Gordon Ramsay', number: '75749483832'},
{ name:'Mr. Tasty', number: '43-4982839'},
{ name:'Dude man', number: '11-33-448382'},
])
const [newName, setNewName] = useState('')
const [newNumber, setNewNumber] = useState('')
const [showAll, setShowAll] = useState(true)
const [filterBy, setFilterBy] = useState('');
const contactsToShow = showAll ? contacts : contacts.filter(contact => contact.name.toUpperCase().search(filterBy) !== -1)
const rows = () => contactsToShow.map(contact =>
<Contact
key={contact.name}
name={contact.name}
number={contact.number}
/>
)
const handleContactNameChange = (event) => {
console.log(event.target.value)
setNewName(event.target.value)
}
const handleContactNumberChange = (event) => {
console.log(event.target.value)
setNewNumber(event.target.value)
console.log(newNumber);
}
const handleFiltering = (event) => {
console.log(event.target.value)
setFilterBy(event.target.value)
setShowAll(false)
console.log(filterBy);
}
const addContact = (event) => {
event.preventDefault()
//
if(newName === '') return true
if(newNumber === '') return true
let dup = false
contacts.forEach(contact => {
if (contact.name === newName) dup = true
})
if (!dup) {
const contactObject = {
name: newName,
number: newNumber
}
setContacts(contacts.concat(contactObject))
setNewName('')
setNewNumber('')
}
}
return (
<div>
<h1>Phonebook</h1>
<form onSubmit={addContact}>
<div>
Filter:<input value={filterBy} onChange={handleFiltering}/>
</div>
Name: <input
value={newName}
onChange={handleContactNameChange}
/><br/>
Number: <input
value={newNumber}
onChange={handleContactNumberChange}
/><br/>
<button type="submit">save</button>
</form>
<ul>
{rows()}
</ul>
</div>
)
}
export default App
我可以尝试什么?我对这样的 React 很陌生。
【问题讨论】:
-
你可以在不使用课程的情况下做到这一点,但我会在你的作业中看到他们想要什么。而且我认为您的
filter方法设置错误,这就是您收到ToUpperCase错误的原因 -
@mph85 是的,他们并没有为此提供进一步的说明或解决方案。这只是学校提供的在线课程。他们还没有引入类组件,所以我现在很难过。
-
问题是你忘了把
contactsToShow变成一个函数。使用const contactsToShow = () => showAll ...和const rows = () => contactsToShow().map(...就可以了:codesandbox.io/s/divine-cloud-vv3ob -
@ChrisG 谢谢!如果您想提交作为答案,我很乐意接受并给您代表。如果可以的话,你介意解释一下为什么在这种情况下需要一个函数吗?我有另一个用例,我使用过滤器只显示“重要”注释,但这是一个布尔字段,并且在没有它的情况下工作。
-
抱歉,我跑题了;您的代码中唯一的“问题”是您没有使用
filterBy.toUpperCase();我修复了我的沙箱。日志记录滞后,因为设置状态是异步的。
标签: javascript reactjs react-hooks