简体   繁体   中英

Transition works in one direction only

I don't know why my transition works in one direction only, with the gif it is better understood, I want it to work both ways, when the completed tasks appear and disappear, thanks for reading.

图片来自 Gyazo

Component TaskItem:

import React, { memo } from 'react'
import styled from "styled-components"

//STYLES

const DIV = styled.div`
    max-height: ${
        props => !props.show && props.done ? "0px" : "150px"
    };
    
    opacity: ${
        props => !props.show && props.done ? "0": "1"
    };

    padding: ${
        props => !props.show && props.done ? "0px":"12px 15px"
    };

    overflow: hidden;
    transition: max-height, opacity 1s;
`;

const TR = styled.tr`
    :nth-child(even) {background-color: #f3f3f3;}
    border-bottom: ${
        props => !props.show && props.done ? "none": "1px solid #dddddd"
    };;
`;

const TD = styled.td`
    /* padding: ${props => {
        if (props.show && props.done) {
            return "12px 15px"
        }
        else if (!props.show && props.done) {
            return "0"
        }

        return "12px 15px"
    }}; */
    /* overflow: hidden;
    transition: all 0.3s; */
`;

function TaskRow({ task, toggleDoneTask, show }) {

    return (
        <TR show={show} done={task.done}>
            <TD>
                <DIV show={show} done={task.done}>
                    {task.title}
                </DIV>
            </TD>
            <TD>
                <DIV show={show} done={task.done}>
                    {task.description}
                </DIV>
            </TD>
            <TD>
                <DIV show={show} done={task.done}>
                    <input type="checkbox"
                        checked={task.done}
                        onChange={toggleDoneTask}
                    />
                </DIV>
            </TD>
        </TR>

    )

}


export default memo(TaskRow, (prev, next) => {

    //COMPARE TASK OBJECT

    const prevTaskKeys = Object.keys(prev.task);
    const nextTaskKeys = Object.keys(next.task);

    const sameLength = prevTaskKeys.length === nextTaskKeys.length;
    const sameEntries = prevTaskKeys.every(key => {
        return nextTaskKeys.includes(key) && prev.task[key] === next.task[key];
    });

    //COMPARE PROP SHOW, CHECK IF SHOW CONTROL CHANGE
    const sameShow = prev.show === next.show

    return sameLength && sameEntries && sameShow;
})

Component Tasks:

import React, { useEffect, useReducer } from 'react'
import TaskItem from "./TaskItem";

function saveLocalStorage(tasks) {
    localStorage.setItem('tasks', JSON.stringify(tasks))
}

function TasksReducer(taskItems, { type, task }) {
    switch (type) {
        case 'UPDATE_TAKS': {
            let taskItemsCopy = [...taskItems].map((task) => ({ ...task }))
            let newItems = taskItemsCopy.map((t) => {
                if (t.id === task.id) {
                    t.done = !t.done
                };
                return t;
            })
            saveLocalStorage(newItems)
            return newItems
        }

        case 'ADD_TASK': {
            const newItems = [...taskItems, task]
            saveLocalStorage(newItems)
            return newItems
        }

        default:
            window.alert('INVALID ACTION')
            break;
    }
}

const initialState = JSON.parse(localStorage.getItem('tasks')) || []

//STYLES

const styleTable = {
    'borderCollapse': 'collapse',
    'margin': '25px 0',
    'fontSize': '0.9em',
    'fontFamily': 'sans-serif',
    'minWidth': '400px',
    'boxShadow': '0 0 20px rgba(0, 0, 0, 0.15)'
}

const styleTr = {
    'backgroundColor': '#009879',
    'color': '#ffffff',
    'textAlign': 'left'
}

const styleTh = {
    padding: '12px 15px'
}

function Tasks({ newTask, show }) {
    const [taskItems, dispatch] = useReducer(TasksReducer, initialState);

    useEffect(() => {
        if (!newTask) return
        newTaskHandler({ id: taskItems.length + 1, ...newTask })
    }, [newTask])

    const newTaskHandler = (task) => {
        dispatch({ type: 'ADD_TASK', task })
    }

    const toggleDoneTask = (task) => {
        dispatch({ type: 'UPDATE_TAKS', task })
    }

    return (
        <React.Fragment>
            <h1>learning react </h1>
            <table style={styleTable}>
                <thead>
                    <tr style={styleTr}>
                        <th style={styleTh}>Title</th>
                        <th style={styleTh}>Description</th>
                        <th style={styleTh}>Done</th>
                    </tr>
                </thead>
                <tbody>
                    {
                        taskItems.map((task) => {
                            return <TaskItem
                                        task={task}
                                        key={task.id}
                                        show={show}
                                        toggleDoneTask={() => toggleDoneTask(task)}>
                                    </TaskItem>
                                
                        })
                    }
                </tbody>
            </table>
        </React.Fragment>
    )
}


export default Tasks

If the complete code is required:

编辑古火-md6ox

---IGNORE-- It looks like your post is mostly code; please add some more details.

when using transition, if you declare for multiple properties then you need to set transition-duration (and any other prop you want) to each of then. the way you wrote only opacity had transition-duration set. you need to add to max-height also:

transition: max-height 1s, opacity 1s;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM