Как дать дочернему компоненту контроль над реагирующим хуком в корневом компоненте - PullRequest
0 голосов
/ 09 апреля 2019

У меня есть приложение, которое добавляет пользователей GitHub в список. Когда я помещаю ввод в форму, пользователь возвращается и добавляется в список. Я хочу, чтобы пользователь был добавлен в список, только если я нажму на пользователя, когда он появится после запроса ресурса. В частности, я хочу, чтобы событие click в дочернем компоненте инициировало запуск ловушки корневым компонентом, чтобы добавить новый элемент в список.

Корневой компонент,

const App = () => {
  const [cards, setCards] = useState([])

  const addNewCard = cardInfo => {
    console.log("addNewCard called ...")
    setCards([cardInfo, ...cards])
  }

  return (
    <div className="App">
      <Form onSubmit={addNewCard}/>
      <CardsList cards={cards} />
    </div>
  )
}

export default App;

Компонент формы,

const Form = props => {
    const [username, setUsername] = useState('');

    const chooseUser = (event) => {
        setUsername(event.target.value)
    } 

    const handleSubmit = event => {
        event.persist();
        console.log("FETCHING ...")
        fetch(`http://localhost:3666/api/users/${username}`, {
        })
        .then(checkStatus)
        .then(data => data.json())
        .then(resp => {
            console.log("RESULT: ", resp)
            props.onSubmit(resp)
            setUsername('')
        })
        .catch(err => console.log(err))
    }

    const checkStatus = response => {
        console.log(response.status)
        const status = response.status
        if (status >= 200 && status <= 399) return response
        else console.log("No results ...")
    }

    return (
        <form onSubmit={handleSubmit}>
            <input
                type="text"
                placeholder="Gitbub username"
                value={username}
                required
                onChange={chooseUser}
                onKeyUp={debounce(handleSubmit, 1000)}
            />
            <button type="submit">Add card</button>
        </form>
    )
}
export default Form;

Компонент списка,

const CardsList = props => {

    return (
        <div>
            {props.cards.map(card => (
                <Card key={card.html_url} {... card} 
                />
            ))}
        </div>
    )
}

export default CardsList

и компонент карты,

const Card = props => {

    const [selected, selectCard] = useState(false)

    return (
        <div style={{margin: '1em'}}>
            <img alt="avatar" src={props.avatar_url} style={{width: '70px'}} />
            <div>
                <div style={{fontWeight: 'bold'}}><a href={props.html_url}>{props.name}</a></div>
                <div>{props.blog}</div>
            </div>

        </div>
    )
}

export default Card 

Прямо сейчас мой компонент формы имеет все управление. Как передать контроль над методом addNewCard в App дочернему компоненту Card?

Заранее спасибо миллион.

1 Ответ

0 голосов
/ 09 апреля 2019

Одним из решений может быть создание метода removeCard в App, который запускается, если не происходит событие click, которое вы хотите контролировать addNewCard.

// App.js
...
const removeCard = username => {
    console.log("Tried to remove card ....", username)
    setCards([...cards.filter(card => card.name != username)])
  }

Затем вы передаете и removeCard, и addNewCard в CardList.

// App.js
...
  <CardsList remove={removeCard} cards={cards} add={addNewCard}/>

Продолжите и передайте эти методы в Card в CardsList.Вам также понадобится некоторая опора на карте, назначенная логическому значению, например «selected».

// CardsList.js
 return (
        <div>
            {props.cards.map(card => (
                <Card key={card.html_url} {... card} 
                remove={handleClick} 
                add={props.add}
                selected={false}
                />
            ))}
        </div>

Настройте событие ловушки и щелчка в дочернем компоненте Card,

// Card.js
...
const [selected, selectCard] = useState(false)
...

и настройте ваши события, чтобы вызвать ловушку и использовать состояние.

// Card.js
...

    return (
        <div style={{margin: '1em', opacity: selected ? '1' : '0.5'}}
            onMouseLeave={() => selected ? null : props.remove(props.name)}
            onClick={() => selectCard(true)}
        >
...

Это на самом деле не переносит контроль над addNewCard с формы на карту, но в конечном итоге заставляет пользовательский интерфейс следовать состоянию компонента карты.

...