реагируйте, исправьте, почему кнопка не обновляет свой вид после нажатия

#javascript #reactjs #redux #react-redux

Вопрос:

итак, я создавал панель администратора для своего приложения, а главное окно-панель со списком пользователей, поэтому я могу удалить или проверить их (на данный момент); часть удаления здесь работает нормально, но я борюсь с частью обновления (проверка пользователя), когда при нажатии на кнопку (АКТИВНЫЙ) react отправляет запрос на сервер для проверки пользователя, и после этого я хочу обновить свою таблицу (этот пользователь с идентификатором 51, на который я нажал сейчас, должен иметь статус «ПРОВЕРЕНО», вместо «АКТИВНЫЙ»

введите описание изображения здесь

основными вопросами являются:

  • почему статус не обновляется сразу после нажатия (он обновляется после того, как я снова нажимаю на тот же статус, но затем сервер не позволяет отправлять подтверждение 2 раза одному и тому же пользователю)
  • и как я должен сделать это правильно, чтобы статус обновлялся сразу после нажатия, конечно, в зависимости от ответа сервера

код:

Панель мониторинга.jsx

 const Dashboard = () => {
const isAuth = useSelector(state => state.user.isAuth);
const dashBoardUsers = useSelector(state => state.users);
const dispatch = useDispatch()

useEffect(() => {

    dispatch(getUsers);//axios request to get list of users

}, [dashBoardUsers])

function renderUsersTable() {
    dispatch(getUsers)

    return dashBoardUsers
    .sort(function(a, b) { return a.id > b.id ? 1 : -1})
    .map((user, index) => {
            const { created, email, firstName, id, lastName, roles, status, updated, username, verificationTimesAsked } = user //destructuring
            return (
                <tr key={index}>
                    <td>{id}</td>
                    <td>{username}</td>
                    <td>{email}</td>
                    <td>{firstName}</td>
                    <td>{lastName}</td>
                    {/* <td>{handleStatus(user)}</td> */}
                    <td><UserStatus user={user}/></td>
                    <td>{created}</td>
                    <td>{updated}</td>
                    <td>{roles.map(r => r.name.split("_").pop())   ','.slice(0, -1)}</td>
                    <td>{verificationTimesAsked}</td>
                    <td><button className="btn btn-danger" disabled={hasAdminRole(roles)} onClick={() => deleteUserElement(id)}>Delete</button></td>
                </tr>
            )
        })
}

return (
    <div style={{ marginLeft: '10px', marginRight: '10px' }}>
        <h1 className="text-center">Users Dashboard</h1>
        <div className="text-center" id="panel">
            <button type="button" className="btn-light btn btn-outline-primary" onClick={() => {
                dispatch(getUsers());
            }}>load users</button>
        </div>
        <div></div>

        <table id="usersTable" className="table table-bordered" style={{ marginTop: '15px' }}>
            <tbody>
                <tr>{renderTableHeader()}</tr>
                {renderUsersTable()}
            </tbody>
        </table>
    </div>
);
};

export default Dashboard;
 

Статус пользователя.jsx:

 const UserStatus = (props) => {
const dispatch = useDispatch();
const [currentStatus, setCurrentStatus] = useState("")

useEffect(() => {
    setCurrentStatus(props.user.status);
    
})

return (
    <div>

        <button type='button' className={currentStatus === 'ACTIVE' ? 'greenStatusButton' : 'blueStatusButton'}
            onMouseOver={(e) => mouseOverButtonColor(e, currentStatus)}
            onMouseLeave={(e) => mouseLeaveButtonColor(e, currentStatus)}
            onClick={(e) => handleStatusClick(props.user, e)}>
            <strong>{currentStatus}</strong>
        </button>

    </div>
);

function handleStatusClick(user, e) {
    console.log('status click userId: ');
    console.log(user.id);
    var answer = window.confirm("Verify user with id: "   user.id   "?");
    if (answer) {
        dispatch(verifyUser(user.id))
        e.target.style.backgroundColor = '#e1edff';
        e.target.style.color = '#607ac4';
        e.target.textContent = 'VERIFIED';

    }
    else {
    }
}
 

reducer.js:

 const SET_USERS = "SET_USERS";
const DELETE_USER = "DELETE_USER";
const VERIFY_USER = "VERIFY_USER";

const defaultState =
[

]


export default function userListReducer(state = [], action) {

switch (action.type) {
    case SET_USERS:
        return [...action.payload]
    case DELETE_USER:
        
        return [...state.filter(user => user.id != action.payload)]
    case VERIFY_USER:

        return [...state.map(user => {return user.id === action.payload.id ? 
action.payload : user} )]
        
        // return [...state.filter(user => user.id != action.payload)]   
    default:
        return state
}
}
 

Комментарии:

1. Каково содержание полезной нагрузки действия?

2. для проверки действия. полезная нагрузка-это объект пользователя {идентификатор, имя пользователя, статус…}

Ответ №1:

Не получаю полного контекста, но ответ на эту проблему должен быть где-то внутри вашего действия. Вы используете redux-thunk в качестве промежуточного программного обеспечения? В этом случае ваш метод thunk должен отправить другое действие для обновления хранилища с помощью ответа API.

Комментарии:

1. это просто сбивает меня с толку, потому что после вызова диспетчера(verifyUser(user.id)) -> вызывает асинхронную отправку запроса axios post, после этого редуктор, похоже, меняет массив с новым пользователем(с обновленным статусом), но обновление текста и цвета кнопки работает неправильно, даже если массив обновлен, кнопка и текст отображаются неверно, только после обновления страницы он улавливает изменения