попытаться вызвать объект функции, который использует переменную состояния, измененную внутри useEffect, и получить неопределенную переменную состояния

Поскольку моя переменная состояния currentUser установлена ​​в useEffect, а getJoinRoom требует currentUser, поэтому я установил useCallback для getJoinRoom с состоянием зависимости currentUser, но кажется, что currentUser все еще не установлен при вызове getJoinRoom

Ошибка при подключении TypeError: невозможно прочитать свойство getJoinableRooms из undefined

function App() {
  const [messages, setMessages] = useState([]);
  const [currentUser, setCurrentUser] = useState();
  const [joinableRooms, setJoinableRooms] = useState([]);
  const [joinedRooms, setJoinedRooms] = useState([]);

  const sendSimpleMessage = (text) => {
    // send simple text
    currentUser.sendSimpleMessage({
      text: text,
      roomId: '7b7a1d23-e869-4c19-8eab-e88d5144dd72'
    });
  }

  const subscribeToRoom = (roomId) => {
    setMessages([]);
    currentUser.subscribeToRoomMultipart({
      // roomId: '7b7a1d23-e869-4c19-8eab-e88d5144dd72',
      roomId: roomId,
      hooks: {
        onMessage: message => {
          // console.log('message object: ', message.parts[0].payload.content);
          setMessages(prevMessages => [...prevMessages, message]);
        }
      }
    })
  };

  const getJoinRoom = useCallback(() => {
    currentUser.getJoinableRooms()
      .then(joinableRooms => {
        setJoinableRooms(joinableRooms);
        setJoinedRooms(currentUser.rooms);
      }).catch(err => {
        console.log('Error on getting joinable rooms', err);
      });
  }, [currentUser])

  useEffect(() => {
    const chatManager = new ChatManager({
      instanceLocator: instanceLocator,
      userId: 'Henry',
      tokenProvider: new TokenProvider({
        url: tokenUrl
      })
    });

    chatManager.connect()
      .then(currUser => {
        setCurrentUser(currUser);

        //currUser.getJoinableRooms()
        //  .then(joinableRooms => {
        //    setJoinableRooms(joinableRooms);
        //    setJoinedRooms(currUser.rooms);
        //  }).catch(err => {
        //    console.log('Error on getting joinable rooms', err);
        //  });

        getJoinRoom();

      }).catch(err => {
        console.log('Error on connection', err)
      })

  }, [getJoinRoom]);

  return (
    <div className="app">
      <RoomList
        rooms={[...joinableRooms, ...joinedRooms]}
        subscribeToRoom={subscribeToRoom}
      />
      <MessageList messages={messages} />
      <SendMessageForm sendSimpleMessage={sendSimpleMessage} />
      <NewRoomForm />
    </div>
  );
}

export default App;

person impressiveHen    schedule 16.10.2019    source источник
comment
const getJoinRoom объявляется после оператора useEffect(), поэтому он будет выдавать ReferenceError, когда вы пытаетесь передать [getJoinRoom] в качестве аргумента deps в useEffect()   -  person Patrick Roberts    schedule 16.10.2019
comment
Привет, @PatrickRoberts, я переместил объявление getJoinRoom перед useEffect, но переменная состояния все еще не распознана   -  person impressiveHen    schedule 16.10.2019
comment
Попробуйте использовать [currentUser.id] вместо [currentUser] в массиве зависимостей для useCallback.   -  person Clarity    schedule 16.10.2019
comment
@Clarity currentUser.id не определен   -  person impressiveHen    schedule 16.10.2019


Ответы (1)


Не реагирующий разработчик.

Вы не можете получить доступ к let/const объявленной переменной в TDZ. Вместо этого используйте объявление функции.

person Yazhou Fu    schedule 16.10.2019
comment
Я решил проблему, изменив const на let, как я предполагал, поскольку const не допускает повторного объявления и обновления, а let разрешает обновление, объект функции обновляется и распознается - person impressiveHen; 17.10.2019