Redux状态更改后,组件未重新呈现

时间:2019-08-30 02:32:50

标签: reactjs redux

我有一个导航组件,其颜色取决于redux状态哈希。

我将这个导航组件包含在另一个组件中,在该组件中,我试图实现一种效果,其中链接的颜色及其状态根据我单击的内容而改变。

一切都已连接,我可以在redux-logger中看到状态更改,但是导航组件没有重新呈现。但是,当我将鼠标悬停在链接上时,它会反映出更改。

redux状态看起来像这样

  navProperties: {
    bold: "black",
    dim: "gray",
    social: "#724474",
    socialText: "white",
    socialHover: "#dbb7c8"
  }

当第一次渲染父组件和导航栏时,changeNavProperties(propertiesHash)起作用,并且颜色反映了我在componentWillMount()中设置的内容。

  componentWillMount() {
    this.props.selectNavLink(this.props.match.url);
    this.props.changeNavProperties({
      bold: "black",
      dim: "gray",
      social: "#4d6cb7",
      socialText: "white",
      socialHover: "#738dce"
    });
  }

这是我的行动和减速器

export default function(state = {}, action) {
  switch (action.type) {
    case "CHANGE_NAV_PROPERTIES":
      return action.payload;
    default:
      return state;
  }
}
export function changeNavProperties(newProperties) {
  return {
    type: "CHANGE_NAV_PROPERTIES",
    payload: newProperties
  };
}

这是我在父组件中调用的函数。单击li更改导航栏项目之一的颜色

class Skills extends Component {

  ...

  handleClick = e => {
    if (e.target.innerHTML === "HTML") {
      this.props.changeNavProperties({
        bold: "white",
        dim: "#333333",
        social: "#e44d26",
        socialText: "white",
        socialHover: "#738dce"
      });
    };
  }

  render() {
    return (
      <div className="skills-container">
        <Navbar />
        <ul>
            <li onClick={this.handleClick}>HTML</li>

        ...

      </div>
    );
  }
}
  ...

  function mapStateToProps(state) {
    return {
      selectedNavLink: state.selectedNavLink
    };
  }

  function mapDispatchToProps(dispatch) {
    return bindActionCreators({ selectNavLink, changeNavProperties }, 
  dispatch);
  }

  export default connect(
    mapStateToProps,
    mapDispatchToProps
  )(Skills);


导航栏组件

class Navbar extends Component {

  componentDidMount() {
    this.setNavProperties();
  }

  setNavProperties = () => {
    document.querySelector(
      ".logo h1"
    ).style.color = this.props.navProperties.bold;
    document.querySelector(
      ".navigation hr"
    ).style.borderColor = this.props.navProperties.bold;
    let navLinks = document.querySelectorAll(".navigation a");

    navLinks.forEach(link => {
      link.style.color = this.props.navProperties.dim;
      if (link.getAttribute("href") === this.props.selectedNavLink) {
        link.parentElement.classList.remove("inactive-link");
        link.parentElement.classList.add("active-link");
        link.style.color = this.props.navProperties.bold;
      }
    });

    let socialMedia = document.querySelectorAll(".social-media i");
    socialMedia.forEach(icon => {
      icon.style.background = this.props.navProperties.social;
      icon.style.color = this.props.navProperties.socialText;
    });
  };


  ...


  function mapStateToProps(state) {
    return {
      selectedNavLink: state.selectedNavLink,
      navProperties: state.navProperties
    }; 
  }

  function mapDispatchToProps(dispatch) {
    return bindActionCreators({ selectNavLink }, dispatch);
  }

  export default connect(
    mapStateToProps,
    mapDispatchToProps
  )(Navbar);
}

3 个答案:

答案 0 :(得分:1)

您需要在redux中更新状态,但您并未这样做,只是在收到时返回有效负载

export default function(state = {}, action) {
  switch (action.type) {
    case "CHANGE_NAV_PROPERTIES":
      /*update the state so that you can re-render data in UI*/
      return Object.assign({}, state, {
        selectedNavLink: action.payload
      }); /*do it like the above*/
    default:
      return state;
  }
}

详细阅读以下内容-https://redux.js.org/basics/reducers

答案 1 :(得分:0)

当您调度"CHANGE_NAV_PROPERTIES"动作时,您的有效载荷包含导航属性。

缺少的部分是确保将其正确分配给navProperties

case "CHANGE_NAV_PROPERTIES":
  return {
    ...state,
    navProperties: action.payload // assign it to navProperties key in store
  };

或使用Object.assign()

case "CHANGE_NAV_PROPERTIES":
  return Object.assign({}, state, {
    navProperties: action.payload
  });

答案 2 :(得分:0)

export default function(state = {}, action) {
  switch (action.type) {
    case "CHANGE_NAV_PROPERTIES":
      return action.payload;
    default:
      return state;
  }
}

应该是这样的:

export default function(state = {}, action) {
  switch (action.type) {
    case "CHANGE_NAV_PROPERTIES":
      return { ...state, navProperties: action.payload };
    default:
      return state;
  }
}

提供上述更改的原因是您的方法将覆盖redux存储中的所有内容。简而言之,您可以通过返回action.payload来改变商店。

请原谅我有错字,我用手机写了这个答案。