Reputation:
action;
export const ON_MESSAGE = 'ON_MESSAGE';
export const sendMessage = (text, sender = 'user') => ({
type: ON_MESSAGE,
payload: { text, sender },
});
reducer:
import { ON_MESSAGE } from 'Redux/actions/Chat_action';
import { act } from 'react-dom/test-utils';
const initalState = [{ text: [] }];
const messageReducer = (state = initalState, action) => {
switch (action.type) {
case ON_MESSAGE:
return [...state, action.payload];
default:
return state;
}
};
export default messageReducer;
combine reducer:
import Chat from 'Redux/reducers/Chat_reducer';
export default combineReducers({
Chat,
});
store:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './rootReducer';
export default function configureStore(initialState) {
return createStore(rootReducer, applyMiddleware(thunk));
}
and code:
const Chat = props => {
const dispatch = useDispatch();
const messages = useSelector(state => state.Chat);
const [text, setText] = React.useState('');
console.log(messages);
return (
<Styled.ChatBox>
<Styled.ChatHeader>
<p>Chat Bot</p>
<div>
<FontAwesomeIcon icon={faAngleDown} size="1x" color="white" />
<FontAwesomeIcon icon={faTimes} size="1x" color="white" />
</div>
</Styled.ChatHeader>
<Styled.ChatLog>
{messages.map(message => (
<Styled.ChatMessage>{message.text}</Styled.ChatMessage>
))}
</Styled.ChatLog>
<Styled.ChatInput>
<textarea
value={text}
onChange={e => setText(e.target.value)}
placeholder="Digite aqui sua mensagem"
/>
<button onClick={() => dispatch(sendMessage({ text }))}>
<FontAwesomeIcon icon={faPaperPlane} size="lg" color="black" />
</button>
</Styled.ChatInput>
</Styled.ChatBox>
);
};
basically my initial message appears normally in my chat body but when I type a message and use the dispatch I get the following errors:
Uncaught Error: Objects are not valid as a React child (found: object with keys {text}).
and
The above error occurred in the component:
the problem is here:
<Styled.ChatLog>
{messages.map(message => (
<Styled.ChatMessage>{message.text}</Styled.ChatMessage>
))}
</Styled.ChatLog>
Upvotes: 0
Views: 809
Reputation: 1173
The problem is that your action is expecting individual parameters but you are passing a single object
export const sendMessage = (text, sender = 'user') => ({
type: ON_MESSAGE,
payload: { text, sender },
});
dispatch(sendMessage({ text }))
Because of this, your reducer shape is actually [{ text: { text: "..." } }]
instead of [{ text: "..." }]
This means that message.text
is actually an object { text: '...' }
, causing the error:
<Styled.ChatMessage>{message.text}</Styled.ChatMessage>
To fix this, you need to pass values as individual parameters to your action, like so:
dispatch(sendMessage(text))
Upvotes: 1
Reputation: 2267
You are trying to render array as react child (message.text is an array):
<Styled.ChatLog>
{messages.map(message => (
<Styled.ChatMessage>{message.text}</Styled.ChatMessage>
))}
Try this:
<Styled.ChatLog>
{messages.map(message => (
<Styled.ChatMessage>{message.text.join()}</Styled.ChatMessage>
))}
Upvotes: 0
Reputation: 59
Most probably its an issue with the reducer when you are updating the state..Please check the value of state and action.payload.text.Also, try to use the initial state as an object instead an Array so that accessing keys in easy. In your case keys in the state might be sender and text.
var initialState = { text: ["msg1"] };
action.payload= {text:"msg2",sender:"user"}; Make sure that action that payload.text is like above value.
And finally, merge them like mentioned below. This will add new msg to the array of texts instead of overriding msg every time.
var newState = {"text":Object.assign({},state.text,action.payload)};
You will also need to update the array.map in your jsx.
Upvotes: 0
Reputation: 51
maybe you can change your initalState to an object spread the action payload inside the text array like this:
const initalState = { text: [] };
return [...state, text: [...action.payload]];
Upvotes: 0