--- id: 5a24c314108439a4d4036142 title: Manage State Locally First challengeType: 6 isRequired: false videoUrl: '' localeTitle: Administrar el estado localmente primero --- ## Description
Aquí terminarás de crear el componente DisplayMessages .
## Instructions
Primero, en el método render() , haga que el componente renderice un elemento de input , elemento de button y elemento ul . Cuando el elemento de input cambia, debe activar un método handleChange() . Además, el elemento de input debe representar el valor de la input que se encuentra en el estado del componente. El elemento de button debe activar un método submitMessage() cuando se hace clic. Segundo, escribe estos dos métodos. El método handleChange() debe actualizar la input con lo que el usuario está escribiendo. El método submitMessage() debe concatenar el mensaje actual (almacenado en la input ) a la matriz de messages en el estado local, y borrar el valor de la input . Finalmente, use la ul para mapear sobre la matriz de messages y procesarlos en la pantalla como una lista de elementos li .
## Tests
```yml tests: - text: 'El componente DisplayMessages debe inicializarse con un estado igual a { input: "", messages: [] } .' testString: 'assert((function() { const mockedComponent = Enzyme.mount(React.createElement(DisplayMessages)); const initialState = mockedComponent.state(); return ( typeof initialState === "object" && initialState.input === "" && initialState.messages.length === 0); })(), "The DisplayMessages component should initialize with a state equal to { input: "", messages: [] }.");' - text: 'El componente DisplayMessages debe generar un div contenga un elemento h2 , un elemento de button , un elemento ul y elementos li como elementos li .' testString: 'async () => { const mockedComponent = Enzyme.mount(React.createElement(DisplayMessages)); const waitForIt = (fn) => new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 100)); const state = () => { mockedComponent.setState({messages: ["__TEST__MESSAGE"]}); return waitForIt(() => mockedComponent )}; const updated = await state(); assert(updated.find("div").length === 1 && updated.find("h2").length === 1 && updated.find("button").length === 1 && updated.find("ul").length === 1, "The DisplayMessages component should render a div containing an h2 element, a button element, a ul element, and li elements as children."); }; ' - text: El elemento de input debe representar el valor de input en estado local. testString: 'async () => { const mockedComponent = Enzyme.mount(React.createElement(DisplayMessages)); const waitForIt = (fn) => new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 100)); const causeChange = (c, v) => c.find("input").simulate("change", { target: { value: v }}); const testValue = "__TEST__EVENT__INPUT"; const changed = () => { causeChange(mockedComponent, testValue); return waitForIt(() => mockedComponent )}; const updated = await changed(); assert(updated.find("input").props().value === testValue, "The input element should render the value of input in local state."); }; ' - text: Al llamar al método handleChange debe actualizar el valor de input en estado a la entrada actual. testString: 'async () => { const mockedComponent = Enzyme.mount(React.createElement(DisplayMessages)); const waitForIt = (fn) => new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 100)); const causeChange = (c, v) => c.find("input").simulate("change", { target: { value: v }}); const initialState = mockedComponent.state(); const testMessage = "__TEST__EVENT__MESSAGE__"; const changed = () => { causeChange(mockedComponent, testMessage); return waitForIt(() => mockedComponent )}; const afterInput = await changed(); assert(initialState.input === "" && afterInput.state().input === "__TEST__EVENT__MESSAGE__", "Calling the method handleChange should update the input value in state to the current input."); }; ' - text: Al hacer clic en el botón Add message se debe llamar al método submitMessage que debe agregar la input actual a la matriz de messages en el estado. testString: 'async () => { const mockedComponent = Enzyme.mount(React.createElement(DisplayMessages)); const waitForIt = (fn) => new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 100)); const causeChange = (c, v) => c.find("input").simulate("change", { target: { value: v }}); const initialState = mockedComponent.state(); const testMessage_1 = "__FIRST__MESSAGE__"; const firstChange = () => { causeChange(mockedComponent, testMessage_1); return waitForIt(() => mockedComponent )}; const firstResult = await firstChange(); const firstSubmit = () => { mockedComponent.find("button").simulate("click"); return waitForIt(() => mockedComponent )}; const afterSubmit_1 = await firstSubmit(); const submitState_1 = afterSubmit_1.state(); const testMessage_2 = "__SECOND__MESSAGE__"; const secondChange = () => { causeChange(mockedComponent, testMessage_2); return waitForIt(() => mockedComponent )}; const secondResult = await secondChange(); const secondSubmit = () => { mockedComponent.find("button").simulate("click"); return waitForIt(() => mockedComponent )}; const afterSubmit_2 = await secondSubmit(); const submitState_2 = afterSubmit_2.state(); assert(initialState.messages.length === 0 && submitState_1.messages.length === 1 && submitState_2.messages.length === 2 && submitState_2.messages[1] === testMessage_2, "Clicking the Add message button should call the method submitMessage which should add the current input to the messages array in state."); }; ' - text: El método submitMessage debería borrar la entrada actual. testString: 'async () => { const mockedComponent = Enzyme.mount(React.createElement(DisplayMessages)); const waitForIt = (fn) => new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 100)); const causeChange = (c, v) => c.find("input").simulate("change", { target: { value: v }}); const initialState = mockedComponent.state(); const testMessage = "__FIRST__MESSAGE__"; const firstChange = () => { causeChange(mockedComponent, testMessage); return waitForIt(() => mockedComponent )}; const firstResult = await firstChange(); const firstState = firstResult.state(); const firstSubmit = () => { mockedComponent.find("button").simulate("click"); return waitForIt(() => mockedComponent )}; const afterSubmit = await firstSubmit(); const submitState = afterSubmit.state(); assert(firstState.input === testMessage && submitState.input === "", "The submitMessage method should clear the current input."); }; ' ```
## Challenge Seed
```jsx class DisplayMessages extends React.Component { constructor(props) { super(props); this.state = { input: ", messages: [] } } // add handleChange() and submitMessage() methods here render() { return (

Type in a new Message:

{ /* render an input, button, and ul here */ } { /* change code above this line */ }
); } }; ```
### After Test
```js console.info('after the test'); ```
## Solution
```js // solution required ```