Still play with birds like I hang with mother goose.
React "conditional rendering" ?
I din render, {this.state.variabelinnehållandestatistik ? rendera statistik : <p>ingen statistik tillgänglig</p>}
Jag har stött på ytterligare ett problem. Någon som har något tips på hur jag löser "hasRating" som jag använder överallt lite smidigare?
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const Button = ({ onClick, text }) => {
return (
<>
<button onClick={onClick}>
{text}
</button>
</>
)
}
const Display = ({ text }) => {
return (
<h1>{text}</h1>
)
}
const History = ({ hasRating }) => {
if (!hasRating) {
return (
<>
<h1>statistics</h1>
<p>No feedback given</p>
</>
)
}
return (<h1>statistics</h1>)
}
const Statistics = ({ text, value, hasRating }) => {
if (hasRating) {
return (
<tr>
<td>{text}</td>
<td>{value}</td>
</tr>
)
}
return null
}
const average = (good, bad, total) => {
return ((good - bad) / total)
}
const positive = (good, total) => {
return ((good / total) * 100 + " %")
}
const App = () => {
// save clicks of each button to own state
const [good, setGood] = useState(0)
const [neutral, setNeutral] = useState(0)
const [bad, setBad] = useState(0)
const totalRatings = good + neutral + bad
const hasRatings = totalRatings > 0
return (
<div>
<Display text="give feedback" />
<Button onClick={() => setGood(good + 1)} text="good" />
<Button onClick={() => setNeutral(neutral + 1)} text="neutral" />
<Button onClick={() => setBad(bad + 1)} text="bad" />
<History hasRating={hasRatings} />
<table>
<tbody>
<Statistics text="good" value={good} hasRating={hasRatings} />
<Statistics text="neutral" value={neutral} hasRating={hasRatings} />
<Statistics text="bad" value={bad} hasRating={hasRatings} />
<Statistics text="all" value={totalRatings} hasRating={hasRatings} />
<Statistics text="average" value={average(good, bad, totalRatings)} hasRating={hasRatings} />
<Statistics text="positive" value={positive(good, totalRatings)} hasRating={hasRatings} />
</tbody>
</table>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root')
)
@burton666: Du vill inte att din komponent Statistics ska bry sig om huruvida hasRating är sann eller inte. Den bryr sig bara om hur den ska rita ut "Statistics" så att skicka ner hasRating känns fel. Samma med History.
@EnsamRobot4: Jo jag fick den känslan jag med men vet inte riktigt hur jag ska lösa det.
Jag har stött på ytterligare ett problem. Någon som har något tips på hur jag löser "hasRating" som jag använder överallt lite smidigare?
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const Button = ({ onClick, text }) => {
return (
<>
<button onClick={onClick}>
{text}
</button>
</>
)
}
const Display = ({ text }) => {
return (
<h1>{text}</h1>
)
}
const History = ({ hasRating }) => {
if (!hasRating) {
return (
<>
<h1>statistics</h1>
<p>No feedback given</p>
</>
)
}
return (<h1>statistics</h1>)
}
const Statistics = ({ text, value, hasRating }) => {
if (hasRating) {
return (
<tr>
<td>{text}</td>
<td>{value}</td>
</tr>
)
}
return null
}
const average = (good, bad, total) => {
return ((good - bad) / total)
}
const positive = (good, total) => {
return ((good / total) * 100 + " %")
}
const App = () => {
// save clicks of each button to own state
const [good, setGood] = useState(0)
const [neutral, setNeutral] = useState(0)
const [bad, setBad] = useState(0)
const totalRatings = good + neutral + bad
const hasRatings = totalRatings > 0
return (
<div>
<Display text="give feedback" />
<Button onClick={() => setGood(good + 1)} text="good" />
<Button onClick={() => setNeutral(neutral + 1)} text="neutral" />
<Button onClick={() => setBad(bad + 1)} text="bad" />
<History hasRating={hasRatings} />
<table>
<tbody>
<Statistics text="good" value={good} hasRating={hasRatings} />
<Statistics text="neutral" value={neutral} hasRating={hasRatings} />
<Statistics text="bad" value={bad} hasRating={hasRatings} />
<Statistics text="all" value={totalRatings} hasRating={hasRatings} />
<Statistics text="average" value={average(good, bad, totalRatings)} hasRating={hasRatings} />
<Statistics text="positive" value={positive(good, totalRatings)} hasRating={hasRatings} />
</tbody>
</table>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root')
)
Nu har jag aldrig använt React hooks, så det var intressant att se hur man kan göra det utan class components. Dock känns det lite rörigare att förstå, men är säkert nice då man jobbat med det, globalt state likt Redux.
Var även ett tag sen jag satt med React, så ska se om jag kan lyckas hjälpa dig!
Som ovan nämner så behöver inte Statistics veta om ifall ett objekt har en rating, det ända den vill göra är att printa ut något till DOM, samma gäller History.
Så i din render skulle vi kunna göra exempelvis så här:
<h1>statistics</h1>
{ !hasRatings && <p>No feedback given</p> }
<table>
<tbody>
{
hasRatings &&
<Fragment>
<Statistics text="good" value={good} />
<Statistics text="neutral" value={neutral} />
<Statistics text="bad" value={bad} />
<Statistics text="all" value={totalRatings} />
<Statistics text="average" value={average(good, bad, totalRatings)} />
<Statistics text="positive" value={positive(good, totalRatings)} />
</Fragment>
}
</tbody>
</table>
Jag har valt att ta bort History då jag tycker den funktionen inte har något riktigt syfte. Du kan lika gärna sätta en <h1> i din render här. Sen med en check på hasRatings om den är false så kan du visa No feedback given.
Sedan kan du med hjälp av React.Fragmemt gruppera flera nodes.
Här säger vi att OM hasRatings är true OCH skriv ut detta (vilket alltid är true).
Plockar bort hasRatings från Statistics
const Statistics = ({ text, value }) => {
return (
<tr>
<td>{text}</td>
<td>{value}</td>
</tr>
)
}
TIPS:
Du kan se över om du kan hålla dina värden i en array, så att du kan få ut alla dina värden via en .map(). På så vis slipper du skriva flera olika <Statistics>, då functionen ändå är dynamisk och kan hantera alla värden du skickar in.
Sparar tangenttryck för trötta fingrar och gör koden lite kortare och lättare att jobba med om man skulle vilja utöka.
Exempel
state = {
ratings: [
good = {
text: "textvalue",
value: 1
},
bad = {
text: "textvalue",
value: 2
},
...etc
]
}
this.state.ratings.map((rating, i) => {
return (<Statistics text={rating.text} value={rating.value} key={i} />)
});
Tackar för ett bra svar. Nu har jag ett nytt problem. Hur får jag "handleMaxVote" att returnera en sträng med ett line break? Om jag istället returnerar ett array med ett <br/> element i mitten så funkar det som jag vill men jag får ett felmeddelande i developer-console i chrome ("VM7053:37 Warning: Each child in a list should have a unique "key" prop.").
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const Random = () => Math.floor(Math.random() * anecdotes.length)
const Button = ({ text, onClick }) => {
return (
<button onClick={onClick}>{text}</button>
)
}
const Display = ({text}) => {
return(<p>{text}</p>)
}
const handleVote = (selected, vote, setVote) => {
const tempArray = [...vote]
tempArray[selected]++
setVote(tempArray)
}
const handleMaxVote = (anecdotes, vote) => {
const maxValue = Math.max(...vote)
const maxValueIndex = vote.indexOf(maxValue)
const maxVotedAnecdote = anecdotes[maxValueIndex]
return [maxVotedAnecdote, <br />, "hello"]
}
const App = (props) => {
const [selected, setSelected] = useState(Random())
const [vote, setVote] = useState(new Array(6).fill(0))
return (
<div>
<h1>Anecdote of the day</h1>
<Display text={anecdotes[selected]} />
<Display text={'has ' + vote[selected] + ' votes'} />
<Button text="vote" onClick={() => handleVote(selected, vote, setVote)}/>
<Button text="next anecdote" onClick={() => setSelected(Random())} />
<h1>Anecdote with most votes</h1>
<Display text={handleMaxVote(anecdotes, vote)} />
</div>
)
}
const anecdotes = [
'If it hurts, do it more often',
'Adding manpower to a late software project makes it later!',
'The first 90 percent of the code accounts for the first 90 percent of the development time...The remaining 10 percent of the code accounts for the other 90 percent of the development time.',
'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.',
'Premature optimization is the root of all evil.',
'Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.'
]
ReactDOM.render(
<App anecdotes={anecdotes} />,
document.getElementById('root')
)
Tackar för ett bra svar. Nu har jag ett nytt problem. Hur får jag "handleMaxVote" att returnera en sträng med ett line break? Om jag istället returnerar ett array med ett <br/> element i mitten så funkar det som jag vill men jag får ett felmeddelande i developer-console i chrome ("VM7053:37 Warning: Each child in a list should have a unique "key" prop.").
const handleMaxVote = (anecdotes, vote) => {
const maxValue = Math.max(...vote)
const maxValueIndex = vote.indexOf(maxValue)
const maxVotedAnecdote = anecdotes[maxValueIndex]
return (maxVotedAnecdote + "\nhas " + maxValue + " votes")
}
const App = (props) => {
const [selected, setSelected] = useState(Random())
const [vote, setVote] = useState(new Array(6).fill(0))
return (
<div>
<h1>Anecdote of the day</h1>
<Display text={anecdotes[selected]} />
<Display text={'has ' + vote[selected] + ' votes'} />
<Button text="vote" onClick={() => handleVote(selected, vote, setVote)}/>
<Button text="next anecdote" onClick={() => setSelected(Random())} />
<h1>Anecdote with most votes</h1>
<Display text={handleMaxVote(anecdotes, vote)} />
</div>
)
}
const anecdotes = [
'If it hurts, do it more often',
'Adding manpower to a late software project makes it later!',
'The first 90 percent of the code accounts for the first 90 percent of the development time...The remaining 10 percent of the code accounts for the other 90 percent of the development time.',
'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.',
'Premature optimization is the root of all evil.',
'Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.'
]
Jag kan svara för att just key är en del av React, React använder detta för att nagivera i trädet och minimera uppdatering. Varje key ska vara unik, detta är för att minimera re-renders.
I vanliga fall använder man ett ID från en datakälla eller generarer det via någon helper class, detta är oftast i typen GUID.
Men i enklare fall går det att använda loop-index, även om det inte är så jätte bra.
Kan ju finnas flera keys med value 1, 2, 3 osv och plockar du bort eller lägger till element i din array så blir dessa IDn fel.
Detta är dock inget som gör att ditt program inte fungerar, det handlar snarare om best-practise och prestanda.
Mer info här: stackoverflow
Angående ditt fel så verkar det saknas kod, jag kan inte skapa upp en fiddle och testa, vilket gör det svårt att felsöka bara sådär i forumet
@zaibuf: Jag har uppdatera koden nu och tagit med allt
Har lite funderingar angående koden.
Du passar in arrayen i props till App.
Du hänvisar direkt till din array "ancedotes" på ett flertal ställen, vad använder du props till?
I din handleMaxVote passar du in två olika arrayer, en för dina textvärden och en som jag antar håller i rösterna?
Enklast hade varit om du använt en array av object där varje ancedote har sitt textvärde och sin vote.
Då skulle du kunna köra en reduce på arrayen, där du plockar ut den med högst värde på vote.
Exempel fiddle
För att få bort ditt error kan du göra såhär:
const handleMaxVote = (anecdotes, vote) => {
const maxValue = Math.max(...vote);
const maxValueIndex = vote.indexOf(maxValue);
const maxVotedAnecdote = anecdotes[maxValueIndex];
return (
<span>
{maxVotedAnecdote}
<br />
</span>
);
};
Problemet var att din Display renderar ett <p> tag och sen passar du in en hel array med 3 värden. Då gnäller den för den spottar ut en lista men du har inte satt några unika keys.
- Igår Corsair Platform 6: För dig som inte nöjer dig med Ikea-skrivbord 6
- Igår Rykte: Switch 2 släpps i höst – OLED-variant dröjer 26
- Igår Iphones marknadsandel faller i USA 42
- 25 / 4 Airtec Pro Type1 – batteridrivet alternativ till tryckluft på burk 79
- 25 / 4 Nu stiger hårddiskpriserna med uppemot 10 procent 21
- Speldator runt 12k - Funkar detta?1
- Corsair Platform 6: För dig som inte nöjer dig med Ikea-skrivbord7
- Quiz: Vad kan du om Inet?73
- Ny caps lock-symbol i Windows förbryllar HP-användare10
- någon som använder Xpenology ? (NAS)3
- Köpråd för ny gaming dator, runt 25k11
- Elbilar - Tråden för intresserade23189
- Vilket VR-headset ska jag köpa?881
- Oskäligt negativt omdöme Tradera24
- Okänd enhet i enhetshanteraren5
- Säljes ASUS ROG STRIX GeForce GTX 1080 Ti 11GB Gaming OC
- Säljes Gamingdator, 7800X3D, RTX 4080 Super
- Säljes Samsung Galaxy Tab S9 Wi-Fi
- Köpes 24 eller 27 tum minst 144hz
- Säljes MSI GeForce GTX 1070 GAMING X 8G
- Säljes Garderobsrensning, möss och keycaps
- Säljes Acer 4K 144Hz XB273KGP - Gaming Prylar - Aio
- Säljes Spelkoder säljes
- Köpes NUC - gärna Intel 8th gen (Iris) men allt intressant
- Skänkes i386 Laptop Skänkes!
- Ny caps lock-symbol i Windows förbryllar HP-användare10
- Corsair Platform 6: För dig som inte nöjer dig med Ikea-skrivbord7
- Rykte: Switch 2 släpps i höst – OLED-variant dröjer26
- NetonNet varnar om läckta kunduppgifter18
- Premiär på SweClockers! Månadens drop med gamingskärm hos Elgiganten62
- IT-bolag: Teknikstrul är största tidsboven idag38
- Därför blockerar Windows 11 24H2 Start‑menyhack39
- Iphones marknadsandel faller i USA42
- Konsumentverket granskar tio nätbutiker som lurat kunder18
- Airtec Pro Type1 – batteridrivet alternativ till tryckluft på burk79
Externa nyheter
Spelnyheter från FZ
- Xbox-försäljningen dök 31 % årets första kvartal igår
- PS Plus-ägare får vänta på Fallout 4-uppdateringen igår
- Spelhelgen knackar på – den kommer med spel! igår
- Switch 2-rykten – Kan släppas 2024, kontrollerna får magnetfästen igår
- People Can Fly har skrotat sitt "banbrytande" action-RPG Project Dagger igår