0

拜托,我需要帮助来访问<trix-editor>我的Mutation组件中的元素。我React hook useRef()用来访问这个,但得到null. 从Chrome Dev Tools(下图)我可以看到该元素已被引用。我已经尝试了这里这里给出的一些解决方案,但没有运气。问题似乎在于Mutation组件的渲染。我是新手React,所以不确定我是否正确。我究竟做错了什么?预先感谢您的帮助


在此处输入图像描述

我的代码:

const EditProfile = () => {
  const trixInput = useRef(null);
  const [state, setState] = useState({
                              firstName: "",
                              lastName: "",
                              bio: "",
                              avatar: "",
                              gender: "",
                              country: ""
                            });

  let userID
  let { username }    = useParams();
  let userFromStore   = JSON.parse(sessionStorage.getItem('_ev')));
  let history         = useHistory();

  useEffect(() => {
    // trixInput.current.addEventListener("trix-change", event => {
       console.log(trixInput.current); // <<<< this prints null to the screen 
    // })
  },[]);

  if (userFromStore !== username) {
    return (
      <div className="alert">
         <span className="closebtn" onClick={() => history.push("/console")}>&times;</span>
          <strong>Wanning!</strong> Not authorized to access this page.
      </div>
    );
  }
  return (
    <Query query={GetAuthUser}>
      {({ loading, error, data }) => {
        if (loading) return "loading...";
        if (error)   return `Error: ${error}`;

        if (data) {
          let {userId, firstName, lastName, avatar, bio, gender, country} = data.authUser.profile;
          userID = parseInt(userId);

          return (
            <Mutation mutation={UpdateUserProfile}>
              {(editProfile, { loading }) => (
                <div  className="card bg-light col-md-8 offset-md-2 shadow p-3 mb-5 rounded">
                  <article className="card-body">
                    <form onSubmit={ e => {
                      e.preventDefault();
                      editProfile({
                        variables: {
                          userId:    userID,
                          firstName: state.firstName,
                          lastName:  state.lastName,
                          bio:       state.bio,
                          avatar:    state.avatar,
                          gender:    state.gender,
                          country:   state.country
                        }
                      }).then(({ data: { editProfile: { success, errors }  } }) => {
                        success ? alert(success) : alert(errors[0]["message"]);
                      });
                    }}
                    >
                    <div className="form-row mb-3">
                      <div className="col">
                        <input
                          type="text"
                          name="firstName"
                          placeholder="First name"
                          className="form-control"
                          defaultValue={firstName}
                          onChange={e => setState({firstName: e.currentTarget.value})}
                        />
                      </div>
                      <div className="col">
                        <input
                          type="text"
                          name="lastName"
                          placeholder="Last name"
                          className="form-control"
                          defaultValue={lastName}
                          onChange={e => setState({lastName: e.currentTarget.value})}
                        />
                      </div>
                    </div>
                    <div className="form-group">
                      <label className="">Bio</label>
                      <input
                        type="hidden"
                        defaultValue={bio}
                        name="bio"
                        id="bio-body"
                      />
                      // <<< having trouble accessing this ref element
                      <trix-editor input="bio-body" ref={trixInput}/>
                    </div>

                    <input type="submit" className="btn btn-primary" value="Update Profile" disabled={loading}/>
                    </form>
                  </article>
                </div>
              )}
            </Mutation>
          );
        }
      }}
    </Query>
  )
}

export default EditProfile;

更新:对于任何感兴趣的人,通过将 组件提取到不同的文件来解决问题。Mutation原因是Mutation组件没有安装在渲染上,只有Query组件正在安装。解决方案的第一次迭代显示为答案。

4

1 回答 1

0

编辑配置文件组件

import React, { useState } from 'react';
import { Query  } from 'react-apollo';
import { useHistory, useParams } from "react-router-dom";
import { GetAuthUser } from './operations.graphql';
import ProfileMutation from './ProfileMutation'


const EditProfile = (props) => {
  const [state, setState] = useState({
                              firstName: "",
                              lastName: "",
                              bio: "",
                              avatar: "",
                              gender: "",
                              country: ""
                            });

  let { username }    = useParams();
  let userFromStore   = JSON.parse(sessionStorage.getItem('_ev'));
  let history         = useHistory();

  if (userFromStore !== username) {
    return (
      <div className="alert">
         <span className="closebtn" onClick={() => history.push("/console")}>&times;</span>
          <strong>Wanning!</strong> Not authorized to access this page.
      </div>
    );
  }
  return (
    <Query query={GetAuthUser}>
      {({ loading, error, data }) => {
        if (loading) return "loading...";
        if (error)   return `Error: ${error}`;

        return <ProfileMutation state={state} profile={data.authUser.profile} setState={setState}/>
      }}
    </Query>
  )
}

export default EditProfile;

ProfileMutation组件

import React, { useRef, useEffect } from 'react';
import { Mutation } from 'react-apollo';
import { UpdateUserProfile } from './operations.graphql';
import "trix/dist/trix.css";
import "./styles.css"

const ProfileMutation = ({ state, profile, setState }) => {
  const trixInput = useRef('');
  let { userId, firstName, lastName, avatar, bio, gender, country } = profile;
  let userID = parseInt(userId);
  // console.log(firstName)

  useEffect(() => {
   trixInput.current.addEventListener('trix-change', (e) => {
    setState({bio: trixInput.current.value})
      console.log(trixInput.current.value)
    })
  },[trixInput])

  return (
    <Mutation mutation={UpdateUserProfile}>
      {(editProfile, { loading }) => (
        <div  className="card bg-light col-md-8 offset-md-2 shadow p-3 mb-5 rounded">
          <article className="card-body">
            <form onSubmit={ e => {
              e.preventDefault();
              editProfile({
                variables: {
                  userId:    userID,
                  firstName: state.firstName,
                  lastName:  state.lastName,
                  bio:       state.bio,
                  avatar:    state.avatar,
                  gender:    state.gender,
                  country:   state.country
                }
              }).then(({ data: { editProfile: { success, errors }  } }) => {
                success ? alert(success) : alert(errors[0]["message"]);
               //TODO: replace alerts with custom message box
              });
            }}
            >
            <div className="form-row mb-3">
              <div className="col">
                <input
                  type="text"
                  name="firstName"
                  placeholder="First name"
                  className="form-control"
                  defaultValue={firstName}
                  onChange={e => setState({firstName: e.currentTarget.value})}
                />
              </div>
              <div className="col">
                <input
                  type="text"
                  name="lastName"
                  placeholder="Last name"
                  className="form-control"
                  defaultValue={lastName}
                  onChange={e => setState({lastName: e.currentTarget.value})}
                />
              </div>
            </div>
            <div className="form-group">
              <label className="">Bio</label>
              <input
                type="hidden"
                defaultValue={bio}
                name="bio"
                id="bio"
              />
              <trix-editor input="bio" ref={trixInput} />
            </div>

            <input type="submit" className="btn btn-primary" value="Update Profile" disabled={loading}/>
            </form>
          </article>
        </div>
      )}
    </Mutation>
  );
}

export default ProfileMutation;

希望这对某人有帮助!如果有人有更好的解决方案,请在此处发布。谢谢!

于 2020-04-16T19:34:04.547 回答