I’m trying to display “tweets” using a local fetch and it almost works. It randomly doesn’t display some message when posted. Then when posting a new one it posts two at the same time (with the last one which didn’t show previously):
Here is the component Home.js where are the fetch:
function Home() {
const dispatch = useDispatch();
const [message, setMessage] = useState("")
const [characters, setCharacters] = useState([])
const [charactersStyle, setCharactersStyle] = useState({})
const user = useSelector((state) => state.user.value)
const [posted, setPosted] = useState(false)
useEffect(() => {
setCharacters(message.length)
}, [message])
useEffect(() => {
if (message.length > 280) {
setCharactersStyle({ "color": "red" })
}
else { setCharactersStyle({}) }
}, [message])
const handleTweet = () => {
if (message.length > 0 && message.length <= 280) {
const regex = /B#[a-zA-Z]+b(?!;)/
fetch("http://localhost:3000/tweets/new", {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: user.username, message }),
})
.then(response => response.json())
.then(data => {
setMessage("")
setPosted(!posted)
dispatch(add(message.match(regex)))
})
}
}
const fetchTweets = async () => {
const response = await fetch("http://localhost:3000/tweets/all")
const data = await response.json()
console.log(data.tweets)
dispatch(post(data.tweets))
}
useEffect(() => {
fetchTweets();
}, [posted])
return (
<div className={styles.container}>
<h1>Home</h1>
<div className={styles.inputcontainer}>
<textarea className={styles.input} onChange={(e) => setMessage(e.target.value)} value={message} ></textarea>
<div className={styles.charbtn}>
<p className={styles.characters} style={charactersStyle}>{`${characters}/280`}</p>
<button type="button" className={styles.tweetbtn} onClick={() => { handleTweet() }}>Tweet</button>
</div>
</div>
<LastTweets posted={posted} />
</div>
)
}
export default Home;
And the component LastTweets.js where are displayed the tweets:
function LastTweets() {
const tweetsToDisplay = useSelector((state) => state.tweets.value)
console.log(tweetsToDisplay)
let tweets;
if (tweetsToDisplay.length > 0) {
tweets = tweetsToDisplay.map((data, i) => {
return <Tweet key={i} {...data} />
})
}
return (
<div>
{tweets}
</div>
)
}
export default LastTweets;
I first tried to use the get fetch in the LastTweet component but it didn’t work either.