更新 - 从功能性子组件更改状态

Updated - Changing the state from a functional child component

我有三个组件,其中 App 是父组件(基于class)和两个名为 User 的子组件(基于功能) &输入。我已将用户导入应用程序并将输入导入用户。我想通过输入中的值更改名称(有一个按钮 -> onClick)。

Updated The problem is the function in App.jsx(I'm pretty sure the way I try to do it is true).

// App.jsx
Imported User

state = {
    users : [
        {id: 1, fullName: 'Amirreza Amini'},
        {id: 2, fullName: 'John Smith'},
        ...
    ]
};

handleChangeName = name => {
    const editedUsers = [...this.state.users];
    const users = editedUsers.map(user => user.fullName = name);

    this.setState({ users });
};

render() {
    const { users } = this.state;

    const userComponent = users.map(user => (

        <User
            key={user.id}
            fullName={user.fullName}
            edit={() => this.handleChangeName(user.fullName)}
        />

    ));
  

.

// User.jsx
Imported Input

const User = ({ fullName }) => {
    return (
        <section>
            <h1>{ fullName }</h1>

            <Input fullName={fullName} />
        </section>
    );
};

export default User;

.

// Input.jsx

const Input = ({ fullName }) => {
    return (
        <section>
            {/* The value of this input must be the fullName after I clicked the button */}
            <input className="user-edit-input" placeholder={fullName} />
            
            <button className="edit-button" onClick={edit(document.querySelector('.user-edit-input').value)}>Change</button>
        </section>
    );
};

export default Input;

您可以将输入作为道具发送到用户组件的回调。从 Users 中,使用回调函数,再调用一个函数来设置 User 组件中的状态

我认为有两大选择:

选项一 正在将 App.jsx 更改为功能组件并发送函数以将全名更改为 User.jsx 并将全名更改为 Input.jsx 作为让 Input 组件自己改变值的 props

选项二 可以让您的 App.jsx 组件保持原样,使其更安全并允许子组件只处理它实际需要知道的内容,类似地从父 App 组件发送一个函数,因此 Input 组件可以触发发送旧的全名和新的全名,父组件函数将处理其余的过程。

父函数示例:

const updateFullname = (previousName, newName) => {
    // Get previous object data and location in array
    let originalUsersState = this.state.users;
    let originalUser = originalUsersState.filter(
        (user, index) => user.fullName === previousName
    )
    const originalUserIndex = originalUsersState.findIndex(
        (user, index) => user.fullName === previousName
    )
    
    // Create new updated object and insert it to updated object array
    let updatedUser = originalUser
    updatedUser.fullName = newName;
    let updatedUsersState = originalUsersState;
    updatedUsersState[originalUserIndex] = updatedUser;

    // Update the state with the new updated object array
    this.setState(
        {
            users: updatedUsersState
        }
    );
}

新提议的功能和流程的问题代码解决方案的缩写:

// App.jsx
Imported User

state = {
    users : [
        {id: 1, fullName: 'Amirreza Amini'},
        {id: 2, fullName: 'John Smith'},
        ...
    ]
};

handleChangeName = name => {
    const editedUsers = [...this.state.users];
    const users = editedUsers.map(user => user.fullName = name);

    this.setState({ users });
};

const updateFullname = (previousName, newName) => {
    // Get previous object data and location in array
    let originalUsersState = this.state.users;
    let originalUser = originalUsersState.filter(
        (user, index) => user.fullName === previousName
    )
    const originalUserIndex = originalUsersState.findIndex(
        (user, index) => user.fullName === previousName
    )

    // Create new updated object and insert it to updated object array
    let updatedUser = originalUser
    updatedUser.fullName = newName;
    let updatedUsersState = originalUsersState;
    updatedUsersState[originalUserIndex] = updatedUser;

    // Update the state with the new updated object array
    this.setState(
        {
            users: updatedUsersState
        }
    );
}

render() {
    const { users } = this.state;

    const userComponent = users.map(user => (

        <User
            key={user.id}
            fullName={user.fullName}
            updateFullname={updateFullname} 
            edit={() => this.handleChangeName(user.fullName)}
        />

    ));
// User.jsx
Imported Input

const User = ({ fullName, updateFullname }) => {
    return (
        <section>
            <h1>{ fullName }</h1>

            <Input fullName={fullName} updateFullname={updateFullname} />
        </section>
    );
};

export default User;
// Input.jsx

const Input = ({ fullName }) => {
    const [inputValue, setInputValue] = useState(undefined);

    return (
        <section>
            <input className="user-edit-input" value={inputValue} onChange={event => setInputValue(event.target.value)} placeholder={fullName} />
            
            <button className="edit-button" onClick={(fullname, inputValue) => updateFullname}>Change</button>
        </section>
    );
};

export default Input;